static void server_agent (void *args, zctx_t *ctx, void *pipe) { agent_t *self = agent_new (ctx, pipe); zmq_pollitem_t items [] = { { self->pipe, 0, ZMQ_POLLIN, 0 }, { self->router, 0, ZMQ_POLLIN, 0 } }; while (!self->stopped) { // Calculate tickless timer, up to 1 hour uint64_t tickless = zclock_time () + 1000 * 3600; zhash_foreach (self->clients, client_tickless, &tickless); // Poll until at most next timer event int rc = zmq_poll (items, 2, (tickless - zclock_time ()) * ZMQ_POLL_MSEC); if (rc == -1) break; // Context has been shut down // Process incoming message from either socket if (items [0].revents & ZMQ_POLLIN) agent_control_message (self); if (items [1].revents & ZMQ_POLLIN) agent_client_message (self); // Send heartbeats to idle clients as needed zhash_foreach (self->clients, client_ping, self->router); } agent_destroy (&self); }
static void * flcliapi_task (void *context) { agent_t *self = agent_new (context, "inproc://flcliapi"); zmq_pollitem_t items [] = { { self->control, 0, ZMQ_POLLIN, 0 }, { self->router, 0, ZMQ_POLLIN, 0 } }; while (!s_interrupted) { // Calculate tickless timer, up to 1 hour uint64_t tickless = s_clock () + 1000 * 3600; if (self->request && tickless > self->expires) tickless = self->expires; zhash_apply (self->servers, server_tickless, &tickless); int rc = zmq_poll (items, 2, (tickless - s_clock ()) * 1000); if (rc == -1 && errno == ETERM) break; // Context has been shut down if (items [0].revents & ZMQ_POLLIN) agent_control_message (self); if (items [1].revents & ZMQ_POLLIN) agent_router_message (self); // If we're processing a request, dispatch to next server if (self->request) { if (s_clock () >= self->expires) { // Request expired, kill it zmsg_t *reply = zmsg_new ("FAILED"); zmsg_send (&reply, self->control); zmsg_destroy (&self->request); } else { // Find server to talk to, remove any expired ones while (zlist_size (self->actives)) { server_t *server = (server_t *) zlist_first (self->actives); if (s_clock () >= server->expires) { zlist_pop (self->actives); server->alive = 0; } else { zmsg_t *request = zmsg_dup (self->request); zmsg_push (request, server->endpoint); zmsg_send (&request, self->router); break; } } } } // Disconnect and delete any expired servers // Send heartbeats to idle servers if needed zhash_apply (self->servers, server_ping, self->router); } agent_destroy (&self); return NULL; }