void blocking_actor::dequeue(behavior& bhvr, message_id mid) {
  CAF_LOG_TRACE(CAF_MARG(mid, integer_value));
  // try to dequeue from cache first
  if (invoke_from_cache(bhvr, mid)) {
    return;
  }
  // requesting an invalid timeout will reset our active timeout
  uint32_t timeout_id = 0;
  if (mid == invalid_message_id) {
    timeout_id = request_timeout(bhvr.timeout());
  } else {
    request_sync_timeout_msg(bhvr.timeout(), mid);
  }
  // read incoming messages
  for (;;) {
    await_data();
    auto msg = next_message();
    switch (invoke_message(msg, bhvr, mid)) {
      case im_success:
        if (mid == invalid_message_id) {
          reset_timeout(timeout_id);
        }
        return;
      case im_skipped:
        if (msg) {
          push_to_cache(std::move(msg));
        }
        break;
      default:
        // delete msg
        break;
    }
  }
}
Example #2
0
void blocking_actor::dequeue(behavior& bhvr, message_id mid) {
  // try to dequeue from cache first
  if (invoke_from_cache(bhvr, mid)) {
    return;
  }
  // requesting an invalid timeout will reset our active timeout
  auto timeout_id = request_timeout(bhvr.timeout());
  // read incoming messages
  for (;;) {
    await_data();
    auto msg = next_message();
    switch (invoke_message(msg, bhvr, mid)) {
      case im_success:
        reset_timeout(timeout_id);
        return;
      case im_skipped:
        if (msg) {
          push_to_cache(std::move(msg));
        }
        break;
      default:
        // delete msg
        break;
    }
  }
}
Example #3
0
File: commands.c Project: hyper/rqd
static void cmdBroadcast(void *base)
{
	node_t *node = (node_t *) base;
	queue_t *q = NULL;
	message_t *msg;
	
 	assert(node);
	assert(node->handle >= 0);
	assert(node->sysdata);
	logger(node->sysdata->logging, 3,
		"node:%d BROADCAST (flags:%x, mask:%x)",
		node->handle, node->data.flags, node->data.mask);

	// do we have a queue name, or a qid?
	if (BIT_TEST(node->data.mask, DATA_MASK_QUEUE) || BIT_TEST(node->data.mask, DATA_MASK_QUEUEID)) {

		if (BIT_TEST(node->data.mask, DATA_MASK_QUEUE)) {
			q = queue_get_name(node->sysdata->queues, expbuf_string(&node->data.queue));
		}
		else if (BIT_TEST(node->data.mask, DATA_MASK_QUEUEID)) {
			q = queue_get_id(node->sysdata->queues, node->data.qid);
		}

		if (q == NULL) {
			q = queue_create(node->sysdata, expbuf_string(&node->data.queue));
		}

		// by this point, we should have 'q'.
		assert(q);
		
		// create message object.
		msg = next_message(node);
		assert(msg);

		// now that we have a message structure completely filled out with the
		// data from the node, then we need to do something with it.
		assert(0);
	}
	else {
		// we didn't have a queue name, or a queue id.   We need to handle this gracefully.
		assert(0);
	}
}
Example #4
0
/*
 * Print the current active headings.
 * Don't change dot if invoker didn't give an argument.
 */
PUBLIC int
headers(void *v)
{
	int *msgvec;
	int n;
	int flag;
	struct message *mp;
	int size;

	msgvec = v;
	size = screensize();
	n = msgvec[0];
	if (n != 0)
		screen = (n - 1)/size;
	if (screen < 0)
		screen = 0;

	if ((mp = get_message(screen * size + 1)) == NULL) {
		int msgCount;
		msgCount = get_msgCount();
		if (screen * size + 1 > msgCount)
			mp = get_message(msgCount - size + 1);
		if (mp == NULL)
			mp = get_message(1);
	}
	flag = 0;
	if (dot != get_message(n))
		dot = mp;
	for (/*EMPTY*/; mp; mp = next_message(mp)) {
		if (mp->m_flag & MDELETED)
			continue;
		if (flag++ >= size)
			break;
		printhead(get_msgnum(mp));
	}
	if (flag == 0) {
		(void)printf("No more mail.\n");
		return 1;
	}
	return 0;
}
Example #5
0
/**
 * Close GOSS channel.
 */
void gridpack::goss::GOSSUtils::closeGOSSChannel(gridpack::parallel::Communicator &comm)
{
  if (GA_Pgroup_nodeid(p_grp) == 0) {
    // Send final message indicating the channel is being closed
#ifndef GOSS_DEBUG
    std::string buf = "_goss_channel_closed";
    std::auto_ptr<TextMessage> message(p_session->createTextMessage(buf));
    p_producer->send(message.get());
    gridpack::utility::CoarseTimer *timer =
      gridpack::utility::CoarseTimer::instance();
    char sbuf[256];
    sprintf(sbuf,"_goss_channel_closed topic: %s %f",p_current_topic.c_str(),
        timer->currentTime());
    printf("%s\n",sbuf);
    std::string acknowledge_topic("topic.goss.gridpack.");
    acknowledge_topic.append(p_current_topic);
    acknowledge_topic.append(".acknowledge");
    printf("_goss_channel_ack: %s\n",acknowledge_topic.c_str());
    std::auto_ptr<Destination> dest(p_session->createTopic(acknowledge_topic));
    std::auto_ptr<MessageConsumer> consumer(p_session->createConsumer(dest.get()));
    std::cout << "Waiting for messages..."<<std::endl;

    std::auto_ptr<Message> next_message(consumer->receive());
    const TextMessage *txtMsg = dynamic_cast<const TextMessage*>(next_message.get());
    if (txtMsg->getText() != "success") {
      std::cout << "Message failure: "<<txtMsg->getText()<<std::endl;
    }

    if (p_connection) delete p_connection;
    if (p_session) delete p_session;
    if (p_destination) delete p_destination;
    if (p_producer) delete p_producer;
#endif
    p_open = false;
  }
}
Example #6
0
 resumable::resume_result resume(detail::cs_thread*,
                                 execution_unit* host) override {
     auto d = static_cast<Derived*>(this);
     d->m_host = host;
     CPPA_LOG_TRACE("id = " << d->id());
     auto done_cb = [&]() -> bool {
         CPPA_LOG_TRACE("");
         d->bhvr_stack().clear();
         d->bhvr_stack().cleanup();
         d->on_exit();
         if (!d->bhvr_stack().empty()) {
             CPPA_LOG_DEBUG("on_exit did set a new behavior in on_exit");
             d->planned_exit_reason(exit_reason::not_exited);
             return false; // on_exit did set a new behavior
         }
         auto rsn = d->planned_exit_reason();
         if (rsn == exit_reason::not_exited) {
             rsn = exit_reason::normal;
             d->planned_exit_reason(rsn);
         }
         d->cleanup(rsn);
         return true;
     };
     auto actor_done = [&] {
         return    d->bhvr_stack().empty()
                || d->planned_exit_reason() != exit_reason::not_exited;
     };
     // actors without behavior or that have already defined
     // an exit reason must not be resumed
     CPPA_REQUIRE(!d->m_initialized || !actor_done());
     if (!d->m_initialized) {
         d->m_initialized = true;
         auto bhvr = d->make_behavior();
         if (bhvr) d->become(std::move(bhvr));
         // else: make_behavior() might have just called become()
         if (actor_done() && done_cb()) return resume_result::done;
         // else: enter resume loop
     }
     try {
         for (;;) {
             auto ptr = d->next_message();
             if (ptr) {
                 if (d->invoke_message(ptr)) {
                     if (actor_done() && done_cb()) {
                         CPPA_LOG_DEBUG("actor exited");
                         return resume_result::done;
                     }
                     // continue from cache if current message was
                     // handled, because the actor might have changed
                     // its behavior to match 'old' messages now
                     while (d->invoke_message_from_cache()) {
                         if (actor_done() && done_cb()) {
                             CPPA_LOG_DEBUG("actor exited");
                             return resume_result::done;
                         }
                     }
                 }
                 // add ptr to cache if invoke_message
                 // did not reset it (i.e. skipped, but not dropped)
                 if (ptr) {
                     CPPA_LOG_DEBUG("add message to cache");
                     d->push_to_cache(std::move(ptr));
                 }
             }
             else {
                 CPPA_LOG_DEBUG("no more element in mailbox; "
                                "going to block");
                 if (d->mailbox().try_block()) {
                     return resumable::resume_later;
                 }
                 // else: try again
             }
         }
     }
     catch (actor_exited& what) {
         CPPA_LOG_INFO("actor died because of exception: actor_exited, "
                       "reason = " << what.reason());
         if (d->exit_reason() == exit_reason::not_exited) {
             d->quit(what.reason());
         }
     }
     catch (std::exception& e) {
         CPPA_LOG_WARNING("actor died because of exception: "
                          << detail::demangle(typeid(e))
                          << ", what() = " << e.what());
         if (d->exit_reason() == exit_reason::not_exited) {
             d->quit(exit_reason::unhandled_exception);
         }
     }
     catch (...) {
         CPPA_LOG_WARNING("actor died because of an unknown exception");
         if (d->exit_reason() == exit_reason::not_exited) {
             d->quit(exit_reason::unhandled_exception);
         }
     }
     done_cb();
     return resumable::done;
 }
Example #7
0
/* Verify received requests and take the necessary actions
   (return a response, kill the connection ...) */
static apr_status_t replay(serv_ctx_t *servctx,
                           apr_int16_t rtnevents,
                           apr_pool_t *pool)
{
    apr_status_t status = APR_SUCCESS;
    test_server_action_t *action;

    if (rtnevents & APR_POLLIN) {
        if (servctx->message_list == NULL) {
            /* we're not expecting any requests to reach this server! */
            serf__log(TEST_VERBOSE, __FILE__,
                      "Received request where none was expected.\n");

            return SERF_ERROR_ISSUE_IN_TESTSUITE;
        }

        if (servctx->cur_action >= servctx->action_count) {
            char buf[128];
            apr_size_t len = sizeof(buf);

            status = servctx->read(servctx, buf, &len);
            if (! APR_STATUS_IS_EAGAIN(status)) {
                /* we're out of actions! */
                serf__log(TEST_VERBOSE, __FILE__,
                          "Received more requests than expected.\n");

                return SERF_ERROR_ISSUE_IN_TESTSUITE;
            }
            return status;
        }

        action = &servctx->action_list[servctx->cur_action];

        serf__log(TEST_VERBOSE, __FILE__,
                  "POLLIN while replaying action %d, kind: %d.\n",
                  servctx->cur_action, action->kind);

        /* Read the remaining data from the client and kill the socket. */
        if (action->kind == SERVER_IGNORE_AND_KILL_CONNECTION) {
            char buf[128];
            apr_size_t len = sizeof(buf);

            status = servctx->read(servctx, buf, &len);

            if (status == APR_EOF) {
                serf__log(TEST_VERBOSE, __FILE__,
                          "Killing this connection.\n");
                apr_socket_close(servctx->client_sock);
                servctx->client_sock = NULL;
                next_action(servctx);
                return APR_SUCCESS;
            }

            return status;
        }
        else if (action->kind == SERVER_RECV ||
                 (action->kind == SERVER_RESPOND &&
                  servctx->outstanding_responses == 0)) {
            apr_size_t msg_len, len;
            char buf[128];
            test_server_message_t *message;

            message = &servctx->message_list[servctx->cur_message];
            msg_len = strlen(message->text);

            do
            {
                len = msg_len - servctx->message_buf_pos;
                if (len > sizeof(buf))
                    len = sizeof(buf);

                status = servctx->read(servctx, buf, &len);
                if (SERF_BUCKET_READ_ERROR(status))
                    return status;

                if (status == APR_EOF) {
                    serf__log(TEST_VERBOSE, __FILE__,
                              "Server: Client hung up the connection.\n");
                    break;
                }
                if (servctx->options & TEST_SERVER_DUMP)
                    fwrite(buf, len, 1, stdout);

                if (strncmp(buf,
                            message->text + servctx->message_buf_pos,
                            len) != 0) {
                    /* ## TODO: Better diagnostics. */
                    printf("Expected: (\n");
                    fwrite(message->text + servctx->message_buf_pos, len, 1,
                           stdout);
                    printf(")\n");
                    printf("Actual: (\n");
                    fwrite(buf, len, 1, stdout);
                    printf(")\n");

                    return SERF_ERROR_ISSUE_IN_TESTSUITE;
                }

                servctx->message_buf_pos += len;

                if (servctx->message_buf_pos >= msg_len) {
                    next_message(servctx);
                    servctx->message_buf_pos -= msg_len;
                    if (action->kind == SERVER_RESPOND)
                        servctx->outstanding_responses++;
                    if (action->kind == SERVER_RECV)
                        next_action(servctx);
                    break;
                }
            } while (!status);
        }
        else if (action->kind == PROXY_FORWARD) {
            apr_size_t len;
            char buf[BUFSIZE];
            serf_bucket_t *tmp;

            /* Read all incoming data from the client to forward it to the
               server later. */
            do
            {
                len = BUFSIZE;

                status = servctx->read(servctx, buf, &len);
                if (SERF_BUCKET_READ_ERROR(status))
                    return status;

                serf__log(TEST_VERBOSE, __FILE__,
                          "proxy: reading %d bytes %.*s from client with "
                          "status %d.\n",
                          len, len, buf, status);

                if (status == APR_EOF) {
                    serf__log(TEST_VERBOSE, __FILE__,
                              "Proxy: client hung up the connection. Reset the "
                              "connection to the server.\n");
                    /* We have to stop forwarding, if a new connection opens
                       the CONNECT request should not be forwarded to the
                       server. */
                    next_action(servctx);
                }
                if (!servctx->servstream)
                    servctx->servstream = serf__bucket_stream_create(
                                              servctx->allocator,
                                              detect_eof,servctx);
                if (len) {
                    tmp = serf_bucket_simple_copy_create(buf, len,
                                                         servctx->allocator);
                    serf_bucket_aggregate_append(servctx->servstream, tmp);
                }
            } while (!status);
        }
    }
    if (rtnevents & APR_POLLOUT) {
        action = &servctx->action_list[servctx->cur_action];

        serf__log(TEST_VERBOSE, __FILE__,
                  "POLLOUT when replaying action %d, kind: %d.\n", servctx->cur_action,
                  action->kind);

        if (action->kind == SERVER_RESPOND && servctx->outstanding_responses) {
            apr_size_t msg_len;
            apr_size_t len;

            msg_len = strlen(action->text);
            len = msg_len - servctx->action_buf_pos;

            status = servctx->send(servctx,
                                   action->text + servctx->action_buf_pos,
                                   &len);
            if (status != APR_SUCCESS)
                return status;

            if (servctx->options & TEST_SERVER_DUMP)
                fwrite(action->text + servctx->action_buf_pos, len, 1, stdout);

            servctx->action_buf_pos += len;

            if (servctx->action_buf_pos >= msg_len) {
                next_action(servctx);
                servctx->outstanding_responses--;
            }
        }
        else if (action->kind == SERVER_KILL_CONNECTION ||
                 action->kind == SERVER_IGNORE_AND_KILL_CONNECTION) {
            serf__log(TEST_VERBOSE, __FILE__,
                      "Killing this connection.\n");
            apr_socket_close(servctx->client_sock);
            servctx->client_sock = NULL;
            next_action(servctx);
        }
        else if (action->kind == PROXY_FORWARD) {
            apr_size_t len;
            char *buf;

            if (!servctx->proxy_client_sock) {
                serf__log(TEST_VERBOSE, __FILE__, "Proxy: setting up connection "
                          "to server.\n");
                status = create_client_socket(&servctx->proxy_client_sock,
                                              servctx, action->text);
                if (!servctx->clientstream)
                    servctx->clientstream = serf__bucket_stream_create(
                                                servctx->allocator,
                                                detect_eof,servctx);
            }

            /* Send all data received from the server to the client. */
            do
            {
                apr_size_t readlen;

                readlen = BUFSIZE;

                status = serf_bucket_read(servctx->clientstream, readlen,
                                          &buf, &readlen);
                if (SERF_BUCKET_READ_ERROR(status))
                    return status;
                if (!readlen)
                    break;

                len = readlen;

                serf__log(TEST_VERBOSE, __FILE__,
                          "proxy: sending %d bytes to client.\n", len);
                status = servctx->send(servctx, buf, &len);
                if (status != APR_SUCCESS) {
                    return status;
                }
                
                if (len != readlen) /* abort for now, return buf to aggregate
                                       if not everything could be sent. */
                    return APR_EGENERAL;
            } while (!status);
        }
    }
    else if (rtnevents & APR_POLLIN) {
        /* ignore */
    }
    else {
        printf("Unknown rtnevents: %d\n", rtnevents);
        abort();
    }

    return status;
}
 resumable::resume_result resume(execution_unit* new_host,
                                 size_t max_throughput) override {
   CAF_REQUIRE(max_throughput > 0);
   auto d = static_cast<Derived*>(this);
   CAF_LOG_TRACE("id = " << d->id());
   d->host(new_host);
   auto done_cb = [&]() -> bool {
     CAF_LOG_TRACE("");
     d->bhvr_stack().clear();
     d->bhvr_stack().cleanup();
     d->on_exit();
     if (!d->bhvr_stack().empty()) {
       CAF_LOG_DEBUG("on_exit did set a new behavior");
       d->planned_exit_reason(exit_reason::not_exited);
       return false; // on_exit did set a new behavior
     }
     auto rsn = d->planned_exit_reason();
     if (rsn == exit_reason::not_exited) {
       rsn = exit_reason::normal;
       d->planned_exit_reason(rsn);
     }
     d->cleanup(rsn);
     return true;
   };
   auto actor_done = [&]() -> bool {
     if (d->bhvr_stack().empty()
         || d->planned_exit_reason() != exit_reason::not_exited) {
       return done_cb();
     }
     return false;
   };
   // actors without behavior or that have already defined
   // an exit reason must not be resumed
   CAF_REQUIRE(!d->is_initialized()
               || (!d->bhvr_stack().empty()
                   && d->planned_exit_reason() == exit_reason::not_exited));
   std::exception_ptr eptr = nullptr;
   try {
     if (!d->is_initialized()) {
       CAF_LOG_DEBUG("initialize actor");
       d->is_initialized(true);
       auto bhvr = d->make_behavior();
       CAF_LOG_DEBUG_IF(!bhvr, "make_behavior() did not return a behavior, "
                               << "bhvr_stack().empty() = "
                               << std::boolalpha << d->bhvr_stack().empty());
       if (bhvr) {
         // make_behavior() did return a behavior instead of using become()
         CAF_LOG_DEBUG("make_behavior() did return a valid behavior");
         d->become(std::move(bhvr));
       }
       if (actor_done()) {
         CAF_LOG_DEBUG("actor_done() returned true right "
                       << "after make_behavior()");
         return resume_result::done;
       }
     }
     // max_throughput = 0 means infinite
     for (size_t i = 0; i < max_throughput; ++i) {
       auto ptr = d->next_message();
       if (ptr) {
         if (d->invoke_message(ptr)) {
           if (actor_done()) {
             CAF_LOG_DEBUG("actor exited");
             return resume_result::done;
           }
           // continue from cache if current message was
           // handled, because the actor might have changed
           // its behavior to match 'old' messages now
           while (d->invoke_message_from_cache()) {
             if (actor_done()) {
               CAF_LOG_DEBUG("actor exited");
               return resume_result::done;
             }
           }
         }
         // add ptr to cache if invoke_message
         // did not reset it (i.e. skipped, but not dropped)
         if (ptr) {
           CAF_LOG_DEBUG("add message to cache");
           d->push_to_cache(std::move(ptr));
         }
       } else {
         CAF_LOG_DEBUG("no more element in mailbox; going to block");
         if (d->mailbox().try_block()) {
           return resumable::awaiting_message;
         }
         CAF_LOG_DEBUG("try_block() interrupted by new message");
       }
     }
     if (!d->has_next_message() && d->mailbox().try_block()) {
       return resumable::awaiting_message;
     }
     // time's up
     return resumable::resume_later;
   }
   catch (actor_exited& what) {
     CAF_LOG_INFO("actor died because of exception: actor_exited, "
                  "reason = " << what.reason());
     if (d->exit_reason() == exit_reason::not_exited) {
       d->quit(what.reason());
     }
   }
   catch (std::exception& e) {
     CAF_LOG_INFO("actor died because of an exception: "
                  << detail::demangle(typeid(e))
                  << ", what() = " << e.what());
     if (d->exit_reason() == exit_reason::not_exited) {
       d->quit(exit_reason::unhandled_exception);
     }
     eptr = std::current_exception();
   }
   catch (...) {
     CAF_LOG_INFO("actor died because of an unknown exception");
     if (d->exit_reason() == exit_reason::not_exited) {
       d->quit(exit_reason::unhandled_exception);
     }
     eptr = std::current_exception();
   }
   if (eptr) {
     auto opt_reason = d->handle(eptr);
     if (opt_reason) {
       // use exit reason defined by custom handler
       d->planned_exit_reason(*opt_reason);
     }
   }
   if (!actor_done()) {
     // actor has been "revived", try running it again later
     return resumable::resume_later;
   }
   return resumable::done;
 }
Example #9
0
File: commands.c Project: hyper/rqd
//-----------------------------------------------------------------------------
// A request has been received for a queue.  We need take it and pass it to a
// node that can handle the request.
static void cmdRequest(void *base)
{
	node_t *node = (node_t *) base;
	message_t *msg;
	queue_t *q;
	stats_t *stats;

 	assert(node);
 	assert(node->handle >= 0);
	assert(node->sysdata);
	logger(node->sysdata->logging, 3,
		"node:%d REQUEST (flags:%x, mask:%x)", node->handle, node->data.flags, node->data.mask);

	assert(node->sysdata->queues);
	assert(node->sysdata->bufpool);

	// make sure we have the required data. At least payload, and a queueid or queue.
	if (BIT_TEST(node->data.mask, DATA_MASK_PAYLOAD) && (BIT_TEST(node->data.mask, DATA_MASK_QUEUE) || BIT_TEST(node->data.mask, DATA_MASK_QUEUEID))) {

		// create the message object to hold the data.
		assert(node->sysdata->msg_list);
		msg = next_message(node);
		assert(msg);

		// The node should have received a payload command.  It would have been
		// assigned to an appropriate buffer.  We need to move that buffer to the
		// message, where it will be handled from there.
		assert(node->data.payload);
		assert(msg->data == NULL);
		msg->data = node->data.payload;
		node->data.payload = NULL;
		
		// if message is NOREPLY, then we dont need some bits.  However, we will need to send a DELIVERED.
		if (BIT_TEST(node->data.flags, DATA_FLAG_NOREPLY)) {
			BIT_SET(msg->flags, FLAG_MSG_NOREPLY);
			assert(msg->source_id == 0);

			// the source_node would have been set when the message object was
			// obtained.  But since we dont want it in this mode, we set it to
			// NULL.
			assert(msg->source_node != NULL);
			msg->source_node = NULL;

			assert(BIT_TEST(node->data.mask, DATA_MASK_ID));
			sendDelivered(node, node->data.id);
		}
		else {
			assert(BIT_TEST(msg->flags, FLAG_MSG_NOREPLY) == 0);
		
			// make a note in the msg object, the source node. If a reply is
			// expected, a messageid should also have been supplied, use that for
			// the node_side.
			assert(msg->source_node == node);
			assert(BIT_TEST(node->data.mask, DATA_MASK_ID));
			message_set_origid(msg, node->data.id);
		}
		
		if (BIT_TEST(node->data.mask, DATA_MASK_TIMEOUT)) {
			// set the timeout... 
			message_set_timeout(msg, node->data.timeout);
		}
		
		// find the q object for this queue.
		if (BIT_TEST(node->data.mask, DATA_MASK_QUEUE)) {
			q = queue_get_name(node->sysdata->queues, expbuf_string(&node->data.queue));
		}
		else if (BIT_TEST(node->data.mask, DATA_MASK_QUEUEID)) {
			q = queue_get_id(node->sysdata->queues, node->data.qid);
		}
		else {
			assert(0);
		}
	
		if (q == NULL) {
			// we dont have a queue, so we will need to create one.
			q = queue_create(node->sysdata, expbuf_string(&node->data.queue));
		}
		assert(q);
		assert(ll_count(node->sysdata->queues) > 0);
		
		// add the message to the queue.

		logger(node->sysdata->logging, 2, "processRequest: node:%d, msg_id:%d, q:%d", node->handle, msg->id, q->qid);
		assert(q->sysdata);
		queue_addmsg(q, msg);

		stats = node->sysdata->stats;
		assert(stats);
		stats->requests ++;
	}
	else {
		// required data was not found.
		// need to return some sort of error
		assert(0);
	}
}