int zhttp_client_wait (zhttp_client_t *self, int timeout) { zpoller_t *poller = zpoller_new (self, NULL); void* sock = zpoller_wait (poller, timeout); if (sock) { zpoller_destroy (&poller); return 0; } if (zpoller_expired (poller)) errno = EAGAIN; else errno = ETERM; zpoller_destroy (&poller); return -1; }
void zmonitor (zsock_t *pipe, void *args) { self_t *self = s_self_new (pipe, (zsock_t *) args); // Signal successful initialization zsock_signal (pipe, 0); while (!self->terminated) { zsock_t *which = zpoller_wait (self->poller, -1); if (which == self->pipe) s_self_handle_pipe (self); else if (which == self->sink) s_self_handle_sink (self); else if (zpoller_terminated (self->poller)) break; // Interrupted } s_self_destroy (&self); }
void zauth (zsock_t *pipe, void *unused) { self_t *self = s_self_new (pipe); // Signal successful initialization zsock_signal (pipe, 0); while (!self->terminated) { zsock_t *which = (zsock_t *) zpoller_wait (self->poller, -1); if (which == self->pipe) s_self_handle_pipe (self); else if (which == self->handler) s_self_authenticate (self); else if (zpoller_terminated (self->poller)) break; // Interrupted } s_self_destroy (&self); }
void mlm_stream_simple (zsock_t *pipe, void *args) { stream_engine_t *self = s_stream_engine_new (pipe, (zsock_t *) args); // Signal successful initialization zsock_signal (pipe, 0); while (!self->terminated) { zsock_t *which = (zsock_t *) zpoller_wait (self->poller, -1); if (which == self->cmdpipe) s_stream_engine_handle_command (self); else if (which == self->msgpipe) s_stream_engine_handle_message (self); else if (zpoller_terminated (self->poller)) break; // Interrupted } s_stream_engine_destroy (&self); }
void zyre_log_test (bool verbose) { printf (" * zyre_log: "); zctx_t *ctx = zctx_new (); // Get all incoming log messages void *collector = zsocket_new (ctx, ZMQ_SUB); zsocket_bind (collector, "tcp://127.0.0.1:5555"); zsocket_set_subscribe (collector, ""); // Create a log instance to send log messages zyre_log_t *log = zyre_log_new (ctx, "this is me"); zyre_log_connect (log, "tcp://127.0.0.1:5555"); // Workaround for issue 270; give time for connect to // happen and subscriptions to go to pub socket; 200 // msec should be enough for under valgrind on a slow PC zpoller_t *poller = zpoller_new (collector, NULL); zpoller_wait (poller, 200); // Send some messages zyre_log_info (log, ZRE_LOG_MSG_EVENT_JOIN, NULL, "this is you"); zyre_log_info (log, ZRE_LOG_MSG_EVENT_EXIT, "Pizza time", "this is you"); zyre_log_warning (log, "this is you", "Time flies like an %s", "arrow"); zyre_log_error (log, "this is you", "Fruit flies like a %s", "banana"); int count = 0; while (count < 4) { zre_log_msg_t *msg = zre_log_msg_recv (collector); assert (msg); if (verbose) zre_log_msg_dump (msg); zre_log_msg_destroy (&msg); count++; } zpoller_destroy (&poller); zyre_log_destroy (&log); zctx_destroy (&ctx); printf ("OK\n"); }
// Checks whether client can connect to server static bool s_can_connect (zsock_t **server, zsock_t **client) { int port_nbr = zsock_bind (*server, "tcp://127.0.0.1:*"); assert (port_nbr > 0); int rc = zsock_connect (*client, "tcp://127.0.0.1:%d", port_nbr); assert (rc == 0); zstr_send (*server, "Hello, World"); zpoller_t *poller = zpoller_new (*client, NULL); assert (poller); bool success = (zpoller_wait (poller, 200) == *client); zpoller_destroy (&poller); zsock_destroy (client); zsock_destroy (server); *server = zsock_new (ZMQ_PUSH); assert (*server); *client = zsock_new (ZMQ_PULL); assert (*client); return success; }
static void s_agent_task (void *args, zctx_t *ctx, void *pipe) { // Create agent instance as we start this task agent_t *self = s_agent_new (ctx, pipe); if (!self) // Interrupted return; zpoller_t *poller = zpoller_new (self->pipe, self->handler, NULL); while (!zpoller_terminated (poller) && !self->terminated) { void *which = zpoller_wait (poller, -1); if (which == self->pipe) s_agent_handle_pipe (self); else if (which == self->handler) s_agent_authenticate (self); } // Done, free all agent resources zpoller_destroy (&poller); s_agent_destroy (&self); }
// Checks whether client can connect to server static bool s_can_connect (zactor_t **proxy, zsock_t **faucet, zsock_t **sink, const char *frontend, const char *backend, bool verbose) { assert (frontend); assert (*faucet); int rc = zsock_connect (*faucet, "%s", frontend); assert (rc == 0); assert (backend); assert (*sink); rc = zsock_connect (*sink, "%s", backend); assert (rc == 0); zstr_send (*faucet, "Hello, World"); zpoller_t *poller = zpoller_new (*sink, NULL); assert (poller); bool success = (zpoller_wait (poller, 200) == *sink); zpoller_destroy (&poller); s_create_test_sockets (proxy, faucet, sink, verbose); return success; }
void zyre_node_engine (void *args, zctx_t *ctx, void *pipe) { // Create node instance to pass around zyre_node_t *self = zyre_node_new (ctx, pipe); if (!self) // Interrupted return; zstr_send (self->pipe, "OK"); uint64_t reap_at = zclock_time () + REAP_INTERVAL; zpoller_t *poller = zpoller_new ( self->pipe, self->inbox, zbeacon_socket (self->beacon), NULL); while (!zpoller_terminated (poller)) { int timeout = (int) (reap_at - zclock_time ()); assert (timeout <= REAP_INTERVAL); if (timeout < 0) timeout = 0; void *which = zpoller_wait (poller, timeout); if (which == self->pipe) zyre_node_recv_api (self); else if (which == self->inbox) zyre_node_recv_peer (self); else if (which == zbeacon_socket (self->beacon)) zyre_node_recv_beacon (self); if (zclock_time () >= reap_at) { reap_at = zclock_time () + REAP_INTERVAL; // Ping all peers and reap any expired ones zhash_foreach (self->peers, zyre_node_ping_peer, self); } if (self->terminated) break; } zpoller_destroy (&poller); zyre_node_destroy (&self); }
int main (int argc, char *argv []) { zctx_t *ctx = zctx_new (); // Use the CZMQ zbeacon class to make sure we listen on the // same network interface as our peers zbeacon_t *beacon = zbeacon_new (ctx, ZRE_DISCOVERY_PORT); char *host = zbeacon_hostname (beacon); // Bind to an ephemeral port void *collector = zsocket_new (ctx, ZMQ_SUB); int port = zsocket_bind (collector, "tcp://%s:*", host); zsocket_set_subscribe (collector, ""); // Announce this to all peers we connect to zyre_t *node = zyre_new (ctx); zyre_set_header (node, "X-ZRELOG", "tcp://%s:%d", host, port); zyre_start (node); zpoller_t *poller = zpoller_new (collector, zyre_socket (node), NULL); while (!zctx_interrupted) { void *which = zpoller_wait (poller, -1); if (which == collector) s_print_log_msg (collector); else if (which == zyre_socket (node)) { zmsg_t *msg = zyre_recv (node); if (!msg) break; // Interrupted zmsg_destroy (&msg); } else break; // Interrupted } zyre_destroy (&node); zbeacon_destroy (&beacon); zctx_destroy (&ctx); return 0; }
void upstream_actor (zsock_t *pipe, void *args) { upstream_t *self = s_upstream_new (pipe); zsock_signal (pipe, 0); while (!self->terminated) { if (self->connected) { zframe_t *content = s_upstream_create_content (self); zframe_send (&content, self->push, 0); } zsock_t *which = (zsock_t *) zpoller_wait (self->poller, -1); if (zpoller_terminated (self->poller)) break; else if (which == self->pipe) { s_upstream_handle_pipe (self); } } s_upstream_destroy (&self); }
static void s_agent_task (void *args, zctx_t *ctx, void *pipe) { char *endpoint = zstr_recv (pipe); assert (endpoint); agent_t *self = s_agent_new (ctx, pipe, endpoint); zpoller_t *poller = zpoller_new (self->pipe, self->socket, NULL); while (!self->terminated) { // Poll on API pipe and on monitor socket void *result = zpoller_wait (poller, -1); if (result == NULL) break; // Interrupted else if (result == self->pipe) s_api_command (self); else if (result == self->socket) s_socket_event (self); } zpoller_destroy (&poller); s_agent_destroy (&self); }
void zproxy (zsock_t *pipe, void *unused) { self_t *self = s_self_new (pipe); assert (self); // Signal successful initialization zsock_signal (pipe, 0); while (!self->terminated) { zsock_t *which = (zsock_t *) zpoller_wait (self->poller, -1); if (zpoller_terminated (self->poller)) break; // Interrupted else if (which == self->pipe) s_self_handle_pipe (self); else if (which == self->frontend) s_self_switch (self, self->frontend, self->backend); else if (which == self->backend) s_self_switch (self, self->backend, self->frontend); } s_self_destroy (&self); }
void zpoller_test (bool verbose) { printf (" * zpoller: "); // @selftest // Create a few sockets zsock_t *vent = zsock_new (ZMQ_PUSH); assert (vent); int port_nbr = zsock_bind (vent, "tcp://127.0.0.1:*"); assert (port_nbr != -1); zsock_t *sink = zsock_new (ZMQ_PULL); assert (sink); int rc = zsock_connect (sink, "tcp://127.0.0.1:%d", port_nbr); assert (rc != -1); zsock_t *bowl = zsock_new (ZMQ_PULL); assert (bowl); zsock_t *dish = zsock_new (ZMQ_PULL); assert (dish); // Set up poller zpoller_t *poller = zpoller_new (bowl, dish, NULL); assert (poller); // Add a reader to the existing poller rc = zpoller_add (poller, sink); assert (rc == 0); zstr_send (vent, "Hello, World"); // We expect a message only on the sink zsock_t *which = (zsock_t *) zpoller_wait (poller, -1); assert (which == sink); assert (zpoller_expired (poller) == false); assert (zpoller_terminated (poller) == false); char *message = zstr_recv (which); assert (streq (message, "Hello, World")); zstr_free (&message); // Stop polling reader rc = zpoller_remove (poller, sink); assert (rc == 0); // Removing a non-existent reader shall fail rc = zpoller_remove (poller, sink); assert (rc == -1); assert (errno == EINVAL); // Check we can poll an FD rc = zsock_connect (bowl, "tcp://127.0.0.1:%d", port_nbr); assert (rc != -1); SOCKET fd = zsock_fd (bowl); rc = zpoller_add (poller, (void *) &fd); assert (rc != -1); zstr_send (vent, "Hello again, world"); assert (zpoller_wait (poller, 500) == &fd); // Check zpoller_set_nonstop () zsys_interrupted = 1; zpoller_wait (poller, 0); assert (zpoller_terminated (poller)); zpoller_set_nonstop (poller, true); zpoller_wait (poller, 0); assert (!zpoller_terminated (poller)); zsys_interrupted = 0; zpoller_destroy (&poller); zsock_destroy (&vent); zsock_destroy (&sink); zsock_destroy (&bowl); zsock_destroy (&dish); #ifdef ZMQ_SERVER // Check thread safe sockets zpoller_destroy (&poller); zsock_t *client = zsock_new (ZMQ_CLIENT); assert (client); zsock_t *server = zsock_new (ZMQ_SERVER); assert (server); poller = zpoller_new (client, server, NULL); assert (poller); port_nbr = zsock_bind (server, "tcp://127.0.0.1:*"); assert (port_nbr != -1); rc = zsock_connect (client, "tcp://127.0.0.1:%d", port_nbr); assert (rc != -1); zstr_send (client, "Hello, World"); // We expect a message only on the server which = (zsock_t *) zpoller_wait (poller, -1); assert (which == server); assert (zpoller_expired (poller) == false); assert (zpoller_terminated (poller) == false); message = zstr_recv (which); assert (streq (message, "Hello, World")); zstr_free (&message); zpoller_destroy (&poller); zsock_destroy (&client); zsock_destroy (&server); #endif #if defined (__WINDOWS__) zsys_shutdown(); #endif // @end printf ("OK\n"); }
void zbeacon_test (bool verbose) { printf (" * zbeacon: "); if (verbose) printf ("\n"); // @selftest // Test 1 - two beacons, one speaking, one listening // Create speaker beacon to broadcast our service zactor_t *speaker = zactor_new (zbeacon, NULL); assert (speaker); if (verbose) zstr_sendx (speaker, "VERBOSE", NULL); zsock_send (speaker, "si", "CONFIGURE", 9999); char *hostname = zstr_recv (speaker); if (!*hostname) { printf ("OK (skipping test, no UDP broadcasting)\n"); zactor_destroy (&speaker); free (hostname); return; } free (hostname); // Create listener beacon on port 9999 to lookup service zactor_t *listener = zactor_new (zbeacon, NULL); assert (listener); if (verbose) zstr_sendx (listener, "VERBOSE", NULL); zsock_send (listener, "si", "CONFIGURE", 9999); hostname = zstr_recv (listener); assert (*hostname); free (hostname); // We will broadcast the magic value 0xCAFE byte announcement [2] = { 0xCA, 0xFE }; zsock_send (speaker, "sbi", "PUBLISH", announcement, 2, 100); // We will listen to anything (empty subscription) zsock_send (listener, "sb", "SUBSCRIBE", "", 0); // Wait for at most 1/2 second if there's no broadcasting zsock_set_rcvtimeo (listener, 500); char *ipaddress = zstr_recv (listener); if (ipaddress) { zframe_t *content = zframe_recv (listener); assert (zframe_size (content) == 2); assert (zframe_data (content) [0] == 0xCA); assert (zframe_data (content) [1] == 0xFE); zframe_destroy (&content); zstr_free (&ipaddress); zstr_sendx (speaker, "SILENCE", NULL); } zactor_destroy (&listener); zactor_destroy (&speaker); // Test subscription filter using a 3-node setup zactor_t *node1 = zactor_new (zbeacon, NULL); assert (node1); zsock_send (node1, "si", "CONFIGURE", 5670); hostname = zstr_recv (node1); assert (*hostname); free (hostname); zactor_t *node2 = zactor_new (zbeacon, NULL); assert (node2); zsock_send (node2, "si", "CONFIGURE", 5670); hostname = zstr_recv (node2); assert (*hostname); free (hostname); zactor_t *node3 = zactor_new (zbeacon, NULL); assert (node3); zsock_send (node3, "si", "CONFIGURE", 5670); hostname = zstr_recv (node3); assert (*hostname); free (hostname); zsock_send (node1, "sbi", "PUBLISH", "NODE/1", 6, 250); zsock_send (node2, "sbi", "PUBLISH", "NODE/2", 6, 250); zsock_send (node3, "sbi", "PUBLISH", "RANDOM", 6, 250); zsock_send (node1, "sb", "SUBSCRIBE", "NODE", 4); // Poll on three API sockets at once zpoller_t *poller = zpoller_new (node1, node2, node3, NULL); assert (poller); int64_t stop_at = zclock_mono () + 1000; while (zclock_mono () < stop_at) { long timeout = (long) (stop_at - zclock_mono ()); if (timeout < 0) timeout = 0; void *which = zpoller_wait (poller, timeout * ZMQ_POLL_MSEC); if (which) { assert (which == node1); char *ipaddress, *received; zstr_recvx (node1, &ipaddress, &received, NULL); assert (streq (received, "NODE/2")); zstr_free (&ipaddress); zstr_free (&received); } } zpoller_destroy (&poller); // Stop listening zstr_sendx (node1, "UNSUBSCRIBE", NULL); // Stop all node broadcasts zstr_sendx (node1, "SILENCE", NULL); zstr_sendx (node2, "SILENCE", NULL); zstr_sendx (node3, "SILENCE", NULL); // Destroy the test nodes zactor_destroy (&node1); zactor_destroy (&node2); zactor_destroy (&node3); // @end printf ("OK\n"); }
static void zyre_bridge_actor (zsock_t *pipe, void *args) { // initialization ubx_block_t *b = (ubx_block_t *) args; struct zyre_bridge_info *inf = (struct zyre_bridge_info*) b->private_data; printf("[zyre_bridge]: actor started.\n"); // send signal on pipe socket to acknowledge initialization zsock_signal (pipe, 0); bool terminated = false; zpoller_t *poller = zpoller_new (pipe, zyre_socket (inf->node), NULL); while (!terminated) { void *which = zpoller_wait (poller, -1); // handle msgs from main thread if (which == pipe) { zmsg_t *msg = zmsg_recv (which); if (!msg) break; // Interrupted // only react to TERM signal char *command = zmsg_popstr (msg); if (streq (command, "$TERM")) terminated = true; else { puts ("Invalid pipe message to actor"); } free (command); zmsg_destroy (&msg); } else // handle msgs from zyre network if (which == zyre_socket (inf->node)) { zmsg_t *msg = zmsg_recv (which); if (!msg) { printf("[zyre_bridge]: interrupted!\n"); } char *event = zmsg_popstr (msg); char *peer = zmsg_popstr (msg); char *name = zmsg_popstr (msg); if (streq (event, "ENTER")) printf ("[zyre_bridge]: %s has entered\n", name); else if (streq (event, "EXIT")) printf ("[zyre_bridge]: %s has exited\n", name); else if (streq (event, "SHOUT")) { printf ("[zyre_bridge]: SHOUT received from %s.\n", name); char *group = zmsg_popstr (msg); char *message = zmsg_popstr (msg); // load JSON msg json_t *m; json_error_t error; m= json_loads(message,0,&error); if(!m) { printf("Error parsing JSON payload! line %d: %s\n", error.line, error.text); json_decref(m); return; } printf("%s\n",message); if (json_object_get(m, "type")) { std::string type = json_dumps(json_object_get(m, "type"), JSON_ENCODE_ANY); type = type.substr(1, type.size()-2); // get rid of " characters printf("type: %s\n",json_dumps(json_object_get(m, "type"), JSON_ENCODE_ANY)); for (int i=0; i < inf->input_type_list.size();i++) { //if (json_string_value(json_object_get(m, "type")) == inf->input_type_list[i]){ //printf("type list, type : %s, %s \n", inf->input_type_list[i].c_str(), type.c_str()); if (inf->input_type_list[i].compare(type) == 0) { ubx_type_t* type = ubx_type_get(b->ni, "unsigned char"); ubx_data_t ubx_msg; ubx_msg.data = (void *)json_dumps(json_object_get(m, "payload"), JSON_ENCODE_ANY); printf("message: %s\n",json_dumps(json_object_get(m, "payload"), JSON_ENCODE_ANY)); ubx_msg.len = strlen(json_dumps(json_object_get(m, "payload"), JSON_ENCODE_ANY)); ubx_msg.type = type; __port_write(inf->ports.zyre_in, &ubx_msg); } } } else { printf("Error parsing JSON string! Does not conform to msg model.\n"); } free (group); free (message); } else if (streq (event, "WHISPER")){ char *message = zmsg_popstr (msg); printf ("%s: WHISPER \n%s\n", name, message); free (message); } else if (streq (event, "EVASIVE")) printf ("[zyre_bridge]: %s is being evasive\n", name); free (event); free (peer); free (name); zmsg_destroy (&msg); } } zpoller_destroy (&poller); //TODO: make parametrizable zclock_sleep (100); }
/// // Poll the registered readers for I/O, return first reader that has input. // The reader will be a libzmq void * socket, or a zsock_t or zactor_t // instance as specified in zpoller_new/zpoller_add. The timeout should be // zero or greater, or -1 to wait indefinitely. Socket priority is defined // by their order in the poll list. If you need a balanced poll, use the low // level zmq_poll method directly. If the poll call was interrupted (SIGINT), // or the ZMQ context was destroyed, or the timeout expired, returns NULL. // You can test the actual exit condition by calling zpoller_expired () and // zpoller_terminated (). The timeout is in msec. void *QmlZpoller::wait (int timeout) { return zpoller_wait (self, timeout); };
static void node_task (void *args, zctx_t *ctx, void *pipe) { zyre_t *node = zyre_new (ctx); if (!node) return; // Could not create new node zyre_set_verbose (node); zyre_start (node); int64_t counter = 0; char *to_peer = NULL; // Either of these set, char *to_group = NULL; // and we set a message char *cookie = NULL; zpoller_t *poller = zpoller_new (pipe, zyre_socket (node), NULL); int64_t trigger = zclock_time () + 1000; while (!zctx_interrupted) { void *which = zpoller_wait (poller, randof (1000)); // Any command from parent means EXIT if (which == pipe) break; // Process an event from node if (which == zyre_socket (node)) { zmsg_t *incoming = zyre_recv (node); if (!incoming) break; // Interrupted char *event = zmsg_popstr (incoming); if (streq (event, "ENTER")) { // Always say hello to new peer to_peer = zmsg_popstr (incoming); } else if (streq (event, "EXIT")) { // Always try talk to departed peer to_peer = zmsg_popstr (incoming); } else if (streq (event, "WHISPER")) { // Send back response 1/2 the time if (randof (2) == 0) { to_peer = zmsg_popstr (incoming); cookie = zmsg_popstr (incoming); } } else if (streq (event, "SHOUT")) { to_peer = zmsg_popstr (incoming); to_group = zmsg_popstr (incoming); cookie = zmsg_popstr (incoming); // Send peer response 1/3rd the time if (randof (3) > 0) { free (to_peer); to_peer = NULL; } // Send group response 1/3rd the time if (randof (3) > 0) { free (to_group); to_group = NULL; } } else if (streq (event, "JOIN")) { char *from_peer = zmsg_popstr (incoming); char *group = zmsg_popstr (incoming); printf ("I: %s joined %s\n", from_peer, group); free (from_peer); free (group); } else if (streq (event, "LEAVE")) { char *from_peer = zmsg_popstr (incoming); char *group = zmsg_popstr (incoming); printf ("I: %s left %s\n", from_peer, group); free (from_peer); free (group); } else if (streq (event, "DELIVER")) { char *filename = zmsg_popstr (incoming); char *fullname = zmsg_popstr (incoming); printf ("I: received file %s\n", fullname); free (fullname); free (filename); } free (event); zmsg_destroy (&incoming); // Send outgoing messages if needed if (to_peer) { zyre_whispers (node, to_peer, "%lu", counter++); free (to_peer); to_peer = NULL; } if (to_group) { zyre_shouts (node, to_group, "%lu", counter++); free (to_group); to_group = NULL; } if (cookie) { free (cookie); cookie = NULL; } } if (zclock_time () >= trigger) { trigger = zclock_time () + 1000; char group [10]; sprintf (group, "GROUP%03d", randof (MAX_GROUP)); if (randof (4) == 0) zyre_join (node, group); else if (randof (3) == 0) zyre_leave (node, group); } } zpoller_destroy (&poller); zyre_destroy (&node); }
int main() { if (!getenv("ENDPOINT")) { fprintf (stderr, "variable ENDPOINT must be declared\n"); exit (EXIT_FAILURE); } char *endpoint = strdup(getenv("ENDPOINT")); //1. start malamute zactor_t *broker = s_broker(endpoint); //2. shout about it through zyre zyre_t *node = zyre_new (getenv("USER")); assert (node); char * UUID = strdup (zyre_uuid (node)); zsys_info ("UUID: %s", UUID); bool to_shout = true; //zyre_set_verbose (node); zyre_start (node); zyre_join (node, "MALAMUTE"); zpoller_t *poller = zpoller_new(zyre_socket (node), NULL); time_t last_leader_shout; // 3. get the comments while (!zsys_interrupted) { zsock_t *which = zpoller_wait(poller, 1000); if (time(NULL) - last_leader_shout > 5) { to_shout = true; zstr_free (&UUID); UUID = strdup (zyre_uuid (node)); zstr_free (&endpoint); endpoint = strdup (getenv("ENDPOINT")); zactor_destroy (&broker); broker = s_broker (endpoint); } if (!which && to_shout) { zyre_shouts (node, "MALAMUTE", "%s", endpoint); continue; } zyre_event_t *event = zyre_event_new (node); if (!event) continue; switch (zyre_event_type (event)) { case ZYRE_EVENT_SHOUT: { int r = strcmp (UUID, zyre_event_sender (event)); if (!r) last_leader_shout = time(NULL); if (r >= 0) goto event_destroy; zsys_debug ("UUID: %s, sender: %s, strcmp: %d", UUID, zyre_event_sender (event), r ); to_shout = false; zstr_free (&UUID); UUID = strdup (zyre_event_sender (event)); zstr_free (&endpoint); zmsg_t *msg = zyre_event_msg (event); endpoint = strdup (zmsg_popstr(msg)); zactor_destroy (&broker); broker = s_broker (endpoint); zclock_sleep(1000); break; } } event_destroy: zyre_event_destroy (&event); } zpoller_destroy (&poller); zstr_free (&UUID); zstr_free (&endpoint); zyre_destroy (&node); zactor_destroy (&broker); }
static void s_proxy_task (void *args, zctx_t *ctx, void *command_pipe) { // Confirm to API that we've started up zsocket_signal (command_pipe); zproxy_t *self = (zproxy_t *) args; // Capture socket, if not NULL, receives all data void *capture = NULL; // Create poller to work on all three sockets zpoller_t *poller = zpoller_new (self->frontend, self->backend, command_pipe, NULL); bool stopped = false; while (!stopped) { // Wait for activity on any polled socket, and read incoming message void *which = zpoller_wait (poller, -1); zmq_msg_t msg; zmq_msg_init (&msg); int send_flags; // Flags for outgoing message if (which && zmq_recvmsg (which, &msg, 0) != -1) { send_flags = zsocket_rcvmore (which)? ZMQ_SNDMORE: 0; if (which == self->frontend || which == self->backend) { void *output = which == self->frontend? self->backend: self->frontend; // Loop on all waiting messages, since polling adds a // non-trivial cost per message, especially on OS/X while (true) { if (capture) { zmq_msg_t dup; zmq_msg_init (&dup); zmq_msg_copy (&dup, &msg); if (zmq_sendmsg (capture, &dup, send_flags) == -1) zmq_msg_close (&dup); } if (zmq_sendmsg (output, &msg, send_flags) == -1) { zmq_msg_close (&msg); break; } if (zmq_recvmsg (which, &msg, ZMQ_DONTWAIT) == -1) break; // Presumably EAGAIN send_flags = zsocket_rcvmore (which)? ZMQ_SNDMORE: 0; } } else if (which == command_pipe) { char command [10] = { 0 }; assert (zmq_msg_size (&msg) < 10); memcpy (command, zmq_msg_data (&msg), zmq_msg_size (&msg)); // Execute API command if (streq (command, "PAUSE")) { zpoller_destroy (&poller); poller = zpoller_new (command_pipe, NULL); } else if (streq (command, "RESUME")) { zpoller_destroy (&poller); poller = zpoller_new (self->frontend, self->backend, command_pipe, NULL); } else if (streq (command, "CAPTURE")) { // Capture flow is always PUSH-to-PULL capture = zsocket_new (self->ctx, ZMQ_PUSH); char *endpoint = zstr_recv (command_pipe); if (capture) { int rc = zsocket_connect (capture, "%s", endpoint); assert (rc == 0); } zstr_free (&endpoint); } else if (streq (command, "STOP")) stopped = true; else assert (0); // Cannot happen, so die // Signal to caller that we processed the command zsocket_signal (command_pipe); } else assert (0); // Cannot happen, so die } else break; // Interrupted } zpoller_destroy (&poller); }
int main (int argn, char *argv []) { // Raise theoretical limit on how many ZeroMQ sockets we can create, // though real limit will be set by the process file handle limit. zsys_set_max_sockets (65535); // Test case 1: two servers, bunch of clients. printf ("Starting small test case: "); fflush (stdout); zactor_t *server1 = zactor_new (zgossip, "server1"); assert (server1); zstr_sendx (server1, "SET", "server/animate", "0", NULL); zstr_sendx (server1, "BIND", "inproc://server1", NULL); zactor_t *server2 = zactor_new (zgossip, "server2"); assert (server2); zstr_sendx (server2, "SET", "server/animate", "0", NULL); zstr_sendx (server2, "BIND", "inproc://server2", NULL); zstr_sendx (server2, "CONNECT", "inproc://server1", NULL); zactor_t *client1 = zactor_new (zgossip, "client1"); assert (client1); zstr_sendx (client1, "BIND", "inproc://client1", NULL); zstr_sendx (client1, "PUBLISH", "client1-00", "0000", NULL); zstr_sendx (client1, "PUBLISH", "client1-11", "1111", NULL); zstr_sendx (client1, "PUBLISH", "client1-22", "2222", NULL); zstr_sendx (client1, "CONNECT", "inproc://server1", NULL); zactor_t *client2 = zactor_new (zgossip, "client2"); assert (client2); zstr_sendx (client2, "BIND", "inproc://client2", NULL); zstr_sendx (client2, "CONNECT", "inproc://server1", NULL); zstr_sendx (client2, "PUBLISH", "client2-00", "0000", NULL); zstr_sendx (client2, "PUBLISH", "client2-11", "1111", NULL); zstr_sendx (client2, "PUBLISH", "client2-22", "2222", NULL); zactor_t *client3 = zactor_new (zgossip, "client3"); assert (client3); zstr_sendx (client3, "CONNECT", "inproc://server2", NULL); zactor_t *client4 = zactor_new (zgossip, "client4"); assert (client4); zstr_sendx (client4, "CONNECT", "inproc://server2", NULL); zclock_sleep (100); assert_status (server1, 6); assert_status (server2, 6); assert_status (client1, 6); assert_status (client2, 6); assert_status (client3, 6); assert_status (client4, 6); zactor_destroy (&server1); zactor_destroy (&server2); zactor_destroy (&client1); zactor_destroy (&client2); zactor_destroy (&client3); zactor_destroy (&client4); printf ("OK\n"); // Test case 2: swarm of peers printf ("Starting swarm test case: "); fflush (stdout); // Default limit on file handles is 1024 (POSIX), and fixed setup // costs 8 handles (3 standard I/O plus 5 for CZMQ/libzmq). So the // most nodes we can test by default is (1024 - 8) / 4 = 254. To // test more, run "ulimit -n xxx" beforehand and pass swarm size // as argument to this program. With e.g. Ubuntu, ceiling is 4K // file handles per process, so the largest swarm I've tested is // 1022 nodes. int swarm_size = 254; if (argn >= 2) swarm_size = atoi (argv [1]); printf ("swarm_size=%d ", swarm_size); // The set size defines the total number of properties we spread // across the swarm. By default this is the swarm_size * 5. You can // specify a different set size as second command line argument. int set_size = swarm_size * 5; if (argn >= 3) set_size = atoi (argv [2]); printf ("set_size=%d ", set_size); // Swarm is an array of actors zactor_t *nodes [swarm_size]; // We'll poll all actors for activity (actors act like sockets) zpoller_t *poller = zpoller_new (NULL); assert (poller); // Create swarm uint node_nbr; for (node_nbr = 0; node_nbr < swarm_size; node_nbr++) { nodes [node_nbr] = zactor_new (zgossip, NULL); assert (nodes [node_nbr]); zpoller_add (poller, nodes [node_nbr]); } printf ("."); fflush (stdout); // Interconnect swarm; ever node connects to one arbitrary node to // create a directed graph, then oldest node connects to youngest // node to create a loop, to test we're robust against cycles. for (node_nbr = 0; node_nbr < swarm_size; node_nbr++) { zstr_sendm (nodes [node_nbr], "BIND"); zstr_sendf (nodes [node_nbr], "inproc://swarm-%d", node_nbr); if (node_nbr > 0) { zstr_sendm (nodes [node_nbr], "CONNECT"); zstr_sendf (nodes [node_nbr], "inproc://swarm-%d", randof (node_nbr)); } } zstr_sendm (nodes [0], "CONNECT"); zstr_sendf (nodes [0], "inproc://swarm-%d", node_nbr - 1); printf ("."); fflush (stdout); // Publish the data set randomly across the swarm int item_nbr; for (item_nbr = 0; item_nbr < set_size; item_nbr++) { node_nbr = randof (swarm_size); assert (node_nbr != swarm_size); assert (node_nbr < swarm_size); zstr_sendm (nodes [node_nbr], "PUBLISH"); zstr_sendfm (nodes [node_nbr], "key-%d", item_nbr); zstr_send (nodes [node_nbr], "value"); } printf (". "); fflush (stdout); // Each actor will deliver us tuples; count these until we're done int total = set_size * swarm_size; int pending = total; int64_t ticker = zclock_mono () + 2000; while (pending) { zsock_t *which = (zsock_t *) zpoller_wait (poller, 100); if (!which) { puts (" - stuck test, aborting"); break; } char *command; zstr_recvx (which, &command, NULL); assert (streq (command, "DELIVER")); pending--; freen (command); if (zclock_mono () > ticker) { printf ("(%d%%)", (int) ((100 * (total - pending)) / total)); fflush (stdout); ticker = zclock_mono () + 2000; } } // Destroy swarm for (node_nbr = 0; node_nbr < swarm_size; node_nbr++) zactor_destroy (&nodes [node_nbr]); printf ("(100%%) OK\n"); #if defined (__WINDOWS__) zsys_shutdown(); #endif return 0; }
JNIEXPORT jlong JNICALL Java_org_zeromq_czmq_Zpoller__1_1wait (JNIEnv *env, jclass c, jlong self, jint timeout) { jlong wait_ = (jlong) (intptr_t) zpoller_wait ((zpoller_t *) (intptr_t) self, (int) timeout); return wait_; }
bool GlobalServer_start ( GlobalServer *self ) { #ifdef WIN32 SetConsoleTitle ("GlobalServer"); #endif // WIN32 special ("======================"); special ("=== Global server ===="); special ("======================"); GlobalServerStartupInfo *info = &self->info; zpoller_t *poller; bool isRunning = true; ServerStartupInfo serverInfo; // =================================== // Initialize CLI connection // =================================== // CLI should communicates through BSD sockets zsock_set_router_raw (self->cliConnection, true); if (zsock_bind (self->cliConnection, GLOBAL_SERVER_CLI_ENDPOINT, info->ip, info->cliPort) == -1) { error ("Failed to bind CLI port."); return false; } info ("CLI connection binded on port %s.", zsys_sprintf (GLOBAL_SERVER_CLI_ENDPOINT, info->ip, info->cliPort)); // =================================== // Initialize Zones connection // =================================== if ((info->zonesPort = zsock_bind (self->zonesConnection, GLOBAL_SERVER_ZONES_ENDPOINT, info->ip)) == -1) { error ("Failed to bind zones port."); return false; } info ("Zones connection binded on port %s.", zsys_sprintf (GLOBAL_SERVER_ZONES_ENDPOINT, info->ip, info->zonesPort)); // =================================== // Initialize 1 Barrack Server // =================================== if (!(ServerFactory_initServerInfo (&serverInfo, SERVER_TYPE_BARRACK, BARRACK_SERVER_ROUTER_ID, info->barrackServerIp, info->barrackServerPortCount, info->barrackServerPort, info->zoneWorkersCount, info->ip, info->cliPort, info->sqlInfo.hostname, info->sqlInfo.login, info->sqlInfo.password, info->sqlInfo.database, info->redisInfo.hostname, info->redisInfo.port) )) { error ("[Barrack] Cannot create a new ServerInfo."); return false; } if (!(Server_createProcess (&serverInfo, ZONE_SERVER_EXECUTABLE_NAME))) { error ("[Barrack] Can't launch a new Server process."); return false; } // =================================== // Initialize N Social Server // =================================== for (uint16_t routerId = 0; routerId < info->socialServersCount; routerId++) { ServerFactory_initServerInfo (&serverInfo, SERVER_TYPE_SOCIAL, SOCIAL_SERVER_ROUTER_ID - routerId, info->socialServersIp[routerId], 1, &info->socialServersPorts[routerId], // Only 1 port for each social server info->socialWorkersCount, info->ip, info->cliPort, info->sqlInfo.hostname, info->sqlInfo.login, info->sqlInfo.password, info->sqlInfo.database, info->redisInfo.hostname, info->redisInfo.port ); if (!(Server_createProcess (&serverInfo, ZONE_SERVER_EXECUTABLE_NAME))) { error ("[routerId=%d] Can't launch a new Server process.", routerId); return false; } } // =================================== // Initialize N Zone Server // =================================== for (uint16_t routerId = 0; routerId < info->zoneServersCount; routerId++) { ServerFactory_initServerInfo (&serverInfo, SERVER_TYPE_ZONE, routerId, info->zoneServersIp[routerId], 1, &info->zoneServersPorts[routerId], // Only 1 port for each Zone server info->zoneWorkersCount, info->ip, info->cliPort, info->sqlInfo.hostname, info->sqlInfo.login, info->sqlInfo.password, info->sqlInfo.database, info->redisInfo.hostname, info->redisInfo.port ); if (!(Server_createProcess (&serverInfo, ZONE_SERVER_EXECUTABLE_NAME))) { error ("[routerId=%d] Can't launch a new Server process.", routerId); return false; } } // Define a poller with the zones and the CLI sockets if (!(poller = zpoller_new (self->cliConnection, self->zonesConnection, NULL))) { error ("Global server cannot create a poller."); return false; } // Listens to requests info ("GlobalServer is ready and running."); while (isRunning) { zsock_t *actor = zpoller_wait (poller, -1); typedef int (*GlobalServerRequestHandler) (GlobalServer *self, zsock_t *actor); GlobalServerRequestHandler handler; // Get the correct handler based on the actor if (actor == self->zonesConnection) { handler = GlobalServer_handleZonesRequest; } else if (actor == self->cliConnection) { handler = GlobalServer_handleCliRequest; } else { warning ("An unknown actor talked to the Global Server. Maybe SIGINT signal ?"); break; } switch (handler (self, actor)) { case -1: // ERROR error ("Global Server encountered an error when handling a request."); case -2: // Connection stopped isRunning = false; break; case 0: // OK break; } } return true; }
static void node_actor (zsock_t *pipe, void *args) { zyre_t *node = zyre_new (NULL); if (!node) return; // Could not create new node zyre_set_verbose (node); zyre_set_endpoint (node, "inproc://%s", (char *) args); free (args); // Connect to test hub zyre_gossip_connect (node, "inproc://zyre-hub"); zyre_start (node); zsock_signal (pipe, 0); // Signal "ready" to caller int counter = 0; char *to_peer = NULL; // Either of these set, char *to_group = NULL; // and we set a message char *cookie = NULL; zpoller_t *poller = zpoller_new (pipe, zyre_socket (node), NULL); int64_t trigger = zclock_mono () + 1000; while (true) { void *which = zpoller_wait (poller, randof (1000)); if (!which) break; // Interrupted // $TERM from parent means exit; anything else is breach of // contract so we should assert if (which == pipe) { char *command = zstr_recv (pipe); assert (streq (command, "$TERM")); zstr_free (&command); break; // Finished } // Process an event from node if (which == zyre_socket (node)) { zmsg_t *incoming = zyre_recv (node); if (!incoming) break; // Interrupted char *event = zmsg_popstr (incoming); char *peer = zmsg_popstr (incoming); char *name = zmsg_popstr (incoming); if (streq (event, "ENTER")) // Always say hello to new peer to_peer = strdup (peer); else if (streq (event, "EXIT")) // Always try talk to departed peer to_peer = strdup (peer); else if (streq (event, "WHISPER")) { // Send back response 1/2 the time if (randof (2) == 0) { to_peer = strdup (peer); cookie = zmsg_popstr (incoming); } } else if (streq (event, "SHOUT")) { to_peer = strdup (peer); to_group = zmsg_popstr (incoming); cookie = zmsg_popstr (incoming); // Send peer response 1/3rd the time if (randof (3) > 0) { free (to_peer); to_peer = NULL; } // Send group response 1/3rd the time if (randof (3) > 0) { free (to_group); to_group = NULL; } } else if (streq (event, "JOIN")) { char *group = zmsg_popstr (incoming); printf ("I: %s joined %s\n", name, group); free (group); } else if (streq (event, "LEAVE")) { char *group = zmsg_popstr (incoming); printf ("I: %s left %s\n", name, group); free (group); } free (event); free (peer); free (name); zmsg_destroy (&incoming); // Send outgoing messages if needed if (to_peer) { zyre_whispers (node, to_peer, "%d", counter++); free (to_peer); to_peer = NULL; } if (to_group) { zyre_shouts (node, to_group, "%d", counter++); free (to_group); to_group = NULL; } if (cookie) { free (cookie); cookie = NULL; } } if (zclock_mono () >= trigger) { trigger = zclock_mono () + 1000; char group [10]; sprintf (group, "GROUP%03d", randof (MAX_GROUP)); if (randof (4) == 0) zyre_join (node, group); else if (randof (3) == 0) zyre_leave (node, group); } } zpoller_destroy (&poller); zyre_destroy (&node); }
int main (int argc, char *argv []) { puts (PRODUCT); puts (COPYRIGHT); puts (NOWARRANTY); int argn = 1; bool verbose = false; if (argn < argc && streq (argv [argn], "-h")) { puts ("syntax: hydrad [ directory ]"); puts (" -- defaults to .hydra in current directory"); exit (0); } if (argn < argc && streq (argv [argn], "-v")) { verbose = true; argn++; } // By default, current node runs in .hydra directory; create this if // it's missing (don't create directory passed as argument); char *workdir = ".hydra"; if (argn < argc) workdir = argv [argn++]; else zsys_dir_create (workdir); // ---------------------------------------------------------------------- // This code eventually goes into a reusable hydra actor class // Switch to working directory zsys_info ("hydrad: data store in %s directory", workdir); if (zsys_dir_change (workdir)) { zsys_error ("hydrad: cannot access %s: %s", workdir, strerror (errno)); return 1; } // Check we are the only process currently running here if (zsys_run_as ("hydrad.lock", NULL, NULL)) { zsys_error ("hydrad: cannot start process safely, exiting"); return 1; } // Get node identity from config file, or generate new identity zconfig_t *config = zconfig_load ("hydra.cfg"); if (!config) { // Set defaults for Hydra service config = zconfig_new ("root", NULL); zconfig_put (config, "/server/timeout", "5000"); zconfig_put (config, "/server/background", "0"); zconfig_put (config, "/server/verbose", "0"); } char *identity = zconfig_resolve (config, "/hydra/identity", NULL); if (!identity) { zuuid_t *uuid = zuuid_new (); zconfig_put (config, "/hydra/identity", zuuid_str (uuid)); zconfig_put (config, "/hydra/nickname", "Anonymous"); zconfig_save (config, "hydra.cfg"); zuuid_destroy (&uuid); } // Create store structure, if necessary zsys_dir_create ("content"); zsys_dir_create ("posts"); // Start server and bind to ephemeral TCP port. We can run many // servers on the same box, for testing. zactor_t *server = zactor_new (hydra_server, NULL); if (verbose) zstr_send (server, "VERBOSE"); // Bind Hydra service to ephemeral port and get that port number char *command; int port_nbr; zsock_send (server, "ss", "CONFIGURE", "hydra.cfg"); zsock_send (server, "ss", "BIND", "tcp://*:*"); zsock_send (server, "s", "PORT"); zsock_recv (server, "si", &command, &port_nbr); zsys_info ("hydrad: TCP server started on port=%d", port_nbr); assert (streq (command, "PORT")); free (command); // We're going to use Zyre for discovery and presence, and our own // Hydra protocol for content exchange zyre_t *zyre = zyre_new (NULL); if (verbose) zyre_set_verbose (zyre); char *hostname = zsys_hostname (); char *endpoint = zsys_sprintf ("tcp://%s:%d", hostname, port_nbr); zyre_set_header (zyre, "X-HYDRA", "%s", endpoint); zstr_free (&endpoint); zstr_free (&hostname); if (zyre_start (zyre)) { zsys_info ("hydrad: can't start Zyre discovery service"); zactor_destroy (&server); zyre_destroy (&zyre); return 1; } // When we get a new peer, handle it zpoller_t *poller = zpoller_new (zyre_socket (zyre), NULL); while (!zpoller_terminated (poller)) { void *which = zpoller_wait (poller, -1); if (which == zyre_socket (zyre)) { zyre_event_t *event = zyre_event_new (zyre); if (zyre_event_type (event) == ZYRE_EVENT_ENTER) { zsys_debug ("hydrad: new peer name=%s endpoint=%s", zyre_event_name (event), zyre_event_header (event, "X-HYDRA")); s_handle_peer (zyre_event_header (event, "X-HYDRA"), verbose); } zyre_event_destroy (&event); } else break; } zsys_info ("hydrad: shutting down..."); zpoller_destroy (&poller); // Shutdown all services zactor_destroy (&server); zyre_destroy (&zyre); zconfig_destroy (&config); return 0; }
/// // Poll the registered readers for I/O, return first reader that has input. // The reader will be a libzmq void * socket, or a zsock_t or zactor_t // instance as specified in zpoller_new/zpoller_add. The timeout should be // zero or greater, or -1 to wait indefinitely. Socket priority is defined // by their order in the poll list. If you need a balanced poll, use the low // level zmq_poll method directly. If the poll call was interrupted (SIGINT), // or the ZMQ context was destroyed, or the timeout expired, returns NULL. // You can test the actual exit condition by calling zpoller_expired () and // zpoller_terminated (). The timeout is in msec. void * QZpoller::wait (int timeout) { void * rv = zpoller_wait (self, timeout); return rv; }
void zyre_node_actor (zsock_t *pipe, void *args) { // Create node instance to pass around zyre_node_t *self = zyre_node_new (pipe, args); if (!self) // Interrupted return; // Signal actor successfully initialized zsock_signal (self->pipe, 0); // Loop until the agent is terminated one way or another int64_t reap_at = zclock_mono () + REAP_INTERVAL; while (!self->terminated) { // Start beacon as soon as we can if (self->beacon && self->port <= 0) { // Our hostname is provided by zbeacon zsock_send(self->beacon, "si", "CONFIGURE", self->beacon_port); char *hostname = zstr_recv(self->beacon); // Is UDP broadcast interface available? if (!streq(hostname, "")) { if (zsys_ipv6()) self->port = zsock_bind(self->inbox, "tcp://%s%%%s:*", zsys_ipv6_address(), zsys_interface()); else self->port = zsock_bind(self->inbox, "tcp://%s:*", hostname); if (self->port > 0) { assert(!self->endpoint); // If caller set this, we'd be using gossip if (streq(zsys_interface(), "*")) { char *hostname = zsys_hostname(); self->endpoint = zsys_sprintf("tcp://%s:%d", hostname, self->port); zstr_free(&hostname); } else { self->endpoint = strdup(zsock_endpoint(self->inbox)); } // Set broadcast/listen beacon beacon_t beacon; beacon.protocol[0] = 'Z'; beacon.protocol[1] = 'R'; beacon.protocol[2] = 'E'; beacon.version = BEACON_VERSION; beacon.port = htons(self->port); zuuid_export(self->uuid, beacon.uuid); zsock_send(self->beacon, "sbi", "PUBLISH", (byte *)&beacon, sizeof(beacon_t), self->interval); zsock_send(self->beacon, "sb", "SUBSCRIBE", (byte *) "ZRE", 3); zpoller_add(self->poller, self->beacon); // Start polling on inbox zpoller_add(self->poller, self->inbox); } } zstr_free(&hostname); } int timeout = (int) (reap_at - zclock_mono ()); if (timeout > REAP_INTERVAL) timeout = REAP_INTERVAL; else if (timeout < 0) timeout = 0; zsock_t *which = (zsock_t *) zpoller_wait (self->poller, timeout); if (which == self->pipe) zyre_node_recv_api (self); else if (which == self->inbox) zyre_node_recv_peer (self); else if (self->beacon && (void *) which == self->beacon) zyre_node_recv_beacon (self); else if (self->gossip && (zactor_t *) which == self->gossip) zyre_node_recv_gossip (self); else if (zpoller_terminated (self->poller)) break; // Interrupted, check before expired else if (zpoller_expired (self->poller)) { if (zclock_mono () >= reap_at) { void *item; reap_at = zclock_mono () + REAP_INTERVAL; // Ping all peers and reap any expired ones for (item = zhash_first (self->peers); item != NULL; item = zhash_next (self->peers)) zyre_node_ping_peer (zhash_cursor (self->peers), item, self); } } } zyre_node_destroy (&self); }
static rsRetVal rcvData(){ DEFiRet; if(!listenerList) { listenerList = zlist_new(); if(!listenerList) { errmsg.LogError(0, NO_ERRCODE, "could not allocate list"); ABORT_FINALIZE(RS_RET_ERR); } } zactor_t *authActor; zcert_t *serverCert; if(runModConf->authenticator == 1) { authActor = zactor_new(zauth, NULL); zstr_sendx(authActor, "CURVE", runModConf->clientCertPath, NULL); zsock_wait(authActor); } instanceConf_t *inst; for(inst = runModConf->root; inst != NULL; inst=inst->next) { CHKiRet(addListener(inst)); } zpoller_t *poller = zpoller_new(NULL); if(!poller) { errmsg.LogError(0, NO_ERRCODE, "could not create poller"); ABORT_FINALIZE(RS_RET_ERR); } DBGPRINTF("imczmq: created poller\n"); struct listener_t *pData; pData = zlist_first(listenerList); if(!pData) { errmsg.LogError(0, NO_ERRCODE, "imczmq: no listeners were " "started, input not activated.\n"); ABORT_FINALIZE(RS_RET_NO_RUN); } while(pData) { int rc = zpoller_add(poller, pData->sock); if(rc != 0) { errmsg.LogError(0, NO_ERRCODE, "imczmq: could not add " "socket to poller, input not activated.\n"); ABORT_FINALIZE(RS_RET_NO_RUN); } pData = zlist_next(listenerList); } zframe_t *frame; zsock_t *which = (zsock_t *)zpoller_wait(poller, -1); while(which) { if (zpoller_terminated(poller)) { break; } pData = zlist_first(listenerList); while(pData->sock != which) { pData = zlist_next(listenerList); } if(which == pData->sock) { DBGPRINTF("imczmq: found matching socket\n"); } frame = zframe_recv(which); char *buf = zframe_strdup(frame); if(buf == NULL) { DBGPRINTF("imczmq: null buffer\n"); continue; } smsg_t *pMsg; if(msgConstruct(&pMsg) == RS_RET_OK) { MsgSetRawMsg(pMsg, buf, strlen(buf)); MsgSetInputName(pMsg, s_namep); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp()); MsgSetRcvFromIP(pMsg, glbl.GetLocalHostIP()); MsgSetMSGoffs(pMsg, 0); MsgSetFlowControlType(pMsg, eFLOWCTL_NO_DELAY); MsgSetRuleset(pMsg, pData->ruleset); pMsg->msgFlags = NEEDS_PARSING | PARSE_HOSTNAME; submitMsg2(pMsg); } free(buf); which = (zsock_t *)zpoller_wait(poller, -1); } finalize_it: zframe_destroy(&frame); zpoller_destroy(&poller); pData = zlist_first(listenerList); while(pData) { zsock_destroy(&pData->sock); free(pData->ruleset); pData = zlist_next(listenerList); } zlist_destroy(&listenerList); zactor_destroy(&authActor); zcert_destroy(&serverCert); RETiRet; }
socket poller::wait(int timeout) { void* sock_ptr = zpoller_wait(self_, timeout); return socket(sock_ptr); }
void broker_run (broker_t *self) { // Only accepting requests when executors available. bool accepting_requests = false; while (1) { zsock_t *which = (zsock_t *) zpoller_wait (self->poller, 10); if (which == self->contexts) { puts ("[BROKER] which == self->contexts"); // [context] [request] zmsg_t *msg = zmsg_recv (self->contexts); assert (msg); if (0 != broker_send_to_executor (self, msg)) zlist_append (self->backlog, msg); // Remove contexts from poller if no executors if (zlist_size (self->executor_lb) == 0) { zpoller_remove (self->poller, self->contexts); accepting_requests = false; } } else if (which == self->executors) { puts ("[BROKER] which == self->executors"); // EITHER: // [executor] ["READY"] // [executor] [context] [response] zmsg_t *msg = zmsg_recv (self->executors); assert (msg); zframe_t *executor_addr = zmsg_pop (msg); assert (executor_addr); zframe_t *ctx_or_ready = zmsg_pop (msg); char *context_addr = zframe_strdup (ctx_or_ready); if (strcmp (context_addr, "READY") != 0) { // Forward the response to the correct context addr. // [context] [0] [response] zmsg_prepend (msg, &ctx_or_ready); zmsg_send (&msg, self->contexts); } else { // Got a READY message // Put the executor ID back in the available queue zlist_append (self->executor_lb, executor_addr); // We know at least one executor is now available, // so check and assign backlog tasks. broker_check_backlog (self); // If we now have executors but not accepting requests, // then start polling on the frontend socket. if (!accepting_requests && zlist_size (self->executor_lb)) { zpoller_add (self->poller, self->contexts); accepting_requests = true; } // Destroy the READY message. zmsg_destroy (&msg); } } else if (zpoller_terminated (self->poller)) break; } }