예제 #1
0
파일: zyre_node.c 프로젝트: mvala/zyre
static int
zyre_node_start (zyre_node_t *self)
{
    //  If application didn't bind explicitly, we grab an ephemeral port
    //  on all available network interfaces. This is orthogonal to
    //  beaconing, since we can connect to other peers and they will
    //  gossip our endpoint to others.
    if (!self->bound) {
        self->port = zsock_bind (self->inbox, "tcp://*:*");
        if (self->port < 0)
            return 1;           //  Could not get new port to bind to?
        self->bound = true;
    }
    //  Start UDP beaconing, if the application didn't disable it
    if (self->beacon_port) {
        assert (!self->beacon);
        self->beacon = zbeacon_new (NULL, self->beacon_port);
        if (!self->beacon)
            return 1;               //  Not possible to start beacon

        if (self->interval)
            zbeacon_set_interval (self->beacon, self->interval);
        zpoller_add (self->poller, zbeacon_socket (self->beacon));

        //  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);
        zbeacon_noecho (self->beacon);
        zbeacon_publish (self->beacon, (byte *) &beacon, sizeof (beacon_t));
        zbeacon_subscribe (self->beacon, (byte *) "ZRE", 3);

        //  Our own host endpoint is provided by the beacon
        assert (!self->endpoint);
        self->endpoint = zsys_sprintf ("tcp://%s:%d",
            zbeacon_hostname (self->beacon), self->port);
    }
    else
    if (!self->endpoint) {
        char *hostname = zsys_hostname ();
        self->endpoint = zsys_sprintf ("tcp://%s:%d", hostname, self->port);
        zstr_free (&hostname);
    }
    //  Start polling on inbox
    zpoller_add (self->poller, self->inbox);
    return 0;
}
예제 #2
0
devio_err_e devio_init_poller_sm (devio_t *self)
{
    devio_err_e err = DEVIO_SUCCESS;
    DBE_DEBUG (DBG_DEV_IO | DBG_LVL_TRACE,
            "[dev_io_core:poll_all_sm] Calling init_poller_sm\n");

    /*  Set-up poller */
    if (self->nnodes == 0) {
        err = DEVIO_ERR_NO_NODES;
        goto err_no_nodes;
    }

    /* FIXME: From CZMQ sources: If you need a balanced poll, use
     * the low level zmq_poll method directly
     */
    unsigned int i;
    for (i = 0; i < self->nnodes; ++i) {
        int zerr = zpoller_add (self->poller, self->pipes[i]);
        if (zerr < 0) {
            err = DEVIO_ERR_ALLOC;
            break;
        }
    }

err_no_nodes:
    return err;
}
예제 #3
0
파일: zyre_node.c 프로젝트: opedroso/zyre
static int
zyre_node_start (zyre_node_t *self)
{
    if (self->beacon_port) {
        //  Start beacon discovery
        //  ------------------------------------------------------------------
        assert (!self->beacon);
        self->beacon = zactor_new (zbeacon, NULL);
        if (!self->beacon)
            return 1;               //  Not possible to start beacon

        if (self->verbose)
            zsock_send (self->beacon, "s", "VERBOSE");
    }
    else {
        //  Start gossip discovery
        //  ------------------------------------------------------------------
        //  If application didn't set an endpoint explicitly, grab ephemeral
        //  port on all available network interfaces.
        if (!self->endpoint) {
            const char *iface = zsys_interface ();
            if (streq (iface, ""))
                iface = "*";
            self->port = zsock_bind (self->inbox, "tcp://%s:*", iface);
            assert (self->port > 0);    //  Die on bad interface or port exhaustion

            char *hostname = zsys_hostname ();
            self->endpoint = zsys_sprintf ("tcp://%s:%d", hostname, self->port);
            zstr_free (&hostname);
        }
        assert (self->gossip);
        zstr_sendx (self->gossip, "PUBLISH", zuuid_str (self->uuid), self->endpoint, NULL);
        //  Start polling on zgossip
        zpoller_add (self->poller, self->gossip);
        //  Start polling on inbox
        zpoller_add(self->poller, self->inbox);
    }
    return 0;
}
예제 #4
0
파일: zproxy.c 프로젝트: wangxx2026/czmq
static void
s_self_configure (self_t *self, zsock_t **sock_p, zmsg_t *request, char *name)
{
    char *type_name = zmsg_popstr (request);
    char *endpoints = zmsg_popstr (request);
    if (self->verbose)
        zsys_info ("zmonitor: - %s type=%s attach=%s", name, type_name, endpoints);
    assert (*sock_p == NULL);
    *sock_p = s_create_socket (type_name, endpoints);
    assert (*sock_p);
    zpoller_add (self->poller, *sock_p);
    zstr_free (&type_name);
    zstr_free (&endpoints);
}
예제 #5
0
파일: zmonitor.c 프로젝트: reqshark/czmq
static void
s_self_start (self_t *self)
{
    assert (!self->sink);
    char *endpoint = zsys_sprintf ("inproc://zmonitor-%p", self->monitored);
    int rc;
#if defined (ZMQ_EVENT_ALL)
    rc = zmq_socket_monitor (self->monitored, endpoint, self->events);
    assert (rc == 0);
#endif
    self->sink = zsock_new (ZMQ_PAIR);
    assert (self->sink);
    rc = zsock_connect (self->sink, "%s", endpoint);
    assert (rc == 0);
    zpoller_add (self->poller, self->sink);
    free (endpoint);
}
예제 #6
0
파일: maltcp_ctx.c 프로젝트: ccsdsmo/malc
int maltcp_ctx_poller_add_endpoint(
    void *self,
    mal_poller_t *mal_poller,
    mal_endpoint_t *mal_endpoint) {
  maltcp_poller_data_t *poller_data = (maltcp_poller_data_t *) mal_poller_get_poller_data(mal_poller);
  maltcp_endpoint_data_t *endpoint_data = (maltcp_endpoint_data_t *) mal_endpoint_get_endpoint_data(mal_endpoint);
  int rc = 0;

  clog_debug(maltcp_logger, "maltcp_ctx_poller_add_endpoint(): %s\n", mal_endpoint_get_uri(mal_endpoint));

  maltcp_add_endpoint(poller_data, mal_endpoint);
  if (poller_data->poller == NULL)
    poller_data->poller = zpoller_new(endpoint_data->socket, NULL);
  else
    rc = zpoller_add(poller_data->poller, endpoint_data->socket);

  return rc;
}
예제 #7
0
파일: zproxy.c 프로젝트: maxkozlovsky/czmq
static void
s_self_configure (self_t *self, zsock_t **sock_p, zmsg_t *request, proxy_socket selected_socket)
{
    char *type_name = zmsg_popstr (request);
    assert (type_name);
    char *endpoints = zmsg_popstr (request);
    assert (endpoints);
    if (self->verbose)
        zsys_info ("zproxy: - %s type=%s attach=%s authentication=%s",
            s_self_selected_socket_name (selected_socket), type_name, endpoints,
            s_self_selected_socket_auth (self->auth_type [selected_socket]));
    assert (*sock_p == NULL);
    *sock_p = s_self_create_socket (self, type_name, endpoints, selected_socket);
    assert (*sock_p);
    zpoller_add (self->poller, *sock_p);
    zstr_free (&type_name);
    zstr_free (&endpoints);
}
예제 #8
0
파일: zpoller.c 프로젝트: evoskuil/czmq
zpoller_t *
zpoller_new (void *reader, ...)
{
    zpoller_t *self = (zpoller_t *) zmalloc (sizeof (zpoller_t));
    assert (self);
#ifdef ZMQ_HAVE_POLLER
    self->zmq_poller = zmq_poller_new ();
    assert (self->zmq_poller);
#else
    self->reader_list = zlist_new ();
    assert (self->reader_list);
#endif
    va_list args;
    va_start (args, reader);
    while (reader) {
        if (zpoller_add (self, reader)) {
            zpoller_destroy (&self);
            break;
        }
        reader = va_arg (args, void *);
    }
    va_end (args);
    return self;
}
예제 #9
0
파일: zpoller.c 프로젝트: evoskuil/czmq
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");
}
예제 #10
0
void
zsync_node_engine (void *args, zctx_t *ctx, void *pipe)
{
    int rc;    
    zsync_node_t *self = zsync_node_new ();
    self->ctx = ctx;
    self->zyre = zyre_new (ctx);
    self->zsync_pipe = pipe;
    
    // Join group
    rc = zyre_join (self->zyre, "ZSYNC");
    assert (rc == 0);

    // Give time to interconnect
    zclock_sleep (250);

    zpoller_t *poller = zpoller_new (zyre_socket (self->zyre), self->zsync_pipe, NULL);
    
    // Create thread for file management
    self->file_pipe = zthread_fork (self->ctx, zsync_ftmanager_engine, NULL);
    zpoller_add (poller, self->file_pipe);
    // Create thread for credit management
    self->credit_pipe = zthread_fork (self->ctx, zsync_credit_manager_engine, NULL);
    zpoller_add (poller, self->credit_pipe);

    // Start receiving messages
    printf("[ND] started\n");
    while (!zpoller_terminated (poller)) {
        void *which = zpoller_wait (poller, -1);
        
        if (which == zyre_socket (self->zyre)) {
            zsync_node_recv_from_zyre (self);
        } 
        else
        if (which == self->zsync_pipe) {
            printf("[ND] Recv Agent\n");
            zsync_node_recv_from_agent (self);
        }
        else
        if (which == self->file_pipe) {
            printf("[ND] Recv FT Manager\n");
            zsync_ftm_msg_t *msg = zsync_ftm_msg_recv (self->file_pipe);
            char *receiver = zsync_ftm_msg_receiver (msg);
            char *zyre_uuid = zsync_node_zyre_uuid (self, receiver);
            if (zyre_uuid) {
                char *path = zsync_ftm_msg_path (msg);
                uint64_t sequence = zsync_ftm_msg_sequence (msg);
                uint64_t chunk_size = zsync_ftm_msg_chunk_size (msg);
                uint64_t offset = zsync_ftm_msg_offset (msg);
                zsync_msg_send_req_chunk (pipe, path, chunk_size, offset);
                zsync_msg_t *zsmsg = zsync_msg_recv (pipe);
                zchunk_t *chunk = zsync_msg_chunk (zsmsg);
                zframe_t *frame = zframe_new (zchunk_data (chunk), zchunk_size (chunk));

                zmsg_t *zmsg = zmsg_new ();
                zs_msg_pack_chunk (zmsg, sequence, path, offset, frame);
                
                zyre_whisper (self->zyre, zyre_uuid, &zmsg);
                zsync_ftm_msg_destroy (&msg);
                zsync_msg_destroy (&zsmsg);
            }
        }
        else
        if (which == self->credit_pipe) {
            printf("[ND] Recv Credit Manager\n");
            zsync_credit_msg_t *cmsg = zsync_credit_msg_recv (self->credit_pipe);
            char *receiver = zsync_credit_msg_receiver (cmsg);
            char *zyre_uuid = zsync_node_zyre_uuid (self, receiver);
            if (zyre_uuid) {
                zmsg_t *credit_msg = zsync_credit_msg_credit (cmsg);
                assert (rc == 0);
                zyre_whisper (self->zyre, zyre_uuid, &credit_msg);
            }
            zsync_credit_msg_destroy (&cmsg);
        }
        if (self->terminated) {
            break;
        }
    }
    zpoller_destroy (&poller);
    zsync_node_destroy (&self);
    printf("[ND] stopped\n");
}
예제 #11
0
///
//  Add a reader to be polled. Returns 0 if OK, -1 on failure. The reader may
//  be a libzmq void * socket, a zsock_t instance, or a zactor_t instance.   
int QZpoller::add (void *reader)
{
    int rv = zpoller_add (self, reader);
    return rv;
}
예제 #12
0
///
//  Add a reader to be polled. Returns 0 if OK, -1 on failure. The reader may
//  be a libzmq void * socket, a zsock_t instance, or a zactor_t instance.   
int QmlZpoller::add (void *reader) {
    return zpoller_add (self, reader);
};
예제 #13
0
파일: zyre_node.c 프로젝트: opedroso/zyre
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);
}
예제 #14
0
파일: poller.cpp 프로젝트: BWallet/czmqpp
void poller::add(socket& sock)
{
    zpoller_add(self_, sock.self());
}
예제 #15
0
JNIEXPORT jint JNICALL
Java_org_zeromq_czmq_Zpoller__1_1add (JNIEnv *env, jclass c, jlong self, jlong reader)
{
    jint add_ = (jint) zpoller_add ((zpoller_t *) (intptr_t) self, (void *) (intptr_t) reader);
    return add_;
}
예제 #16
0
파일: imczmq.c 프로젝트: dpocock/rsyslog
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;
}
예제 #17
0
파일: zyre_node.c 프로젝트: Muraad/zyre
static int
zyre_node_start (zyre_node_t *self)
{
    if (self->beacon_port) {
        //  Start beacon discovery
        //  ------------------------------------------------------------------
        assert (!self->beacon);
        self->beacon = zactor_new (zbeacon, NULL);
        if (!self->beacon)
            return 1;               //  Not possible to start beacon

        if (self->verbose)
            zsock_send (self->beacon, "s", "VERBOSE");
            
        //  Our hostname is provided by zbeacon
        zsock_send (self->beacon, "si", "CONFIGURE", self->beacon_port);
        char *hostname = zstr_recv (self->beacon);
        if (streq (hostname, ""))
            return -1;              //  No UDP broadcast interface available

        self->port = zsock_bind (self->inbox, "tcp://%s:*", hostname);
        zstr_free (&hostname);
        assert (self->port > 0);    //  Die on bad interface or port exhaustion
        assert (!self->endpoint);   //  If caller set this, we'd be using gossip
        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);
    }
    else {
        //  Start gossip discovery
        //  ------------------------------------------------------------------
        //  If application didn't set an endpoint explicitly, grab ephemeral
        //  port on all available network interfaces.
        if (!self->endpoint) {
            const char *iface = zsys_interface ();
            if (streq (iface, ""))
                iface = "*";
            self->port = zsock_bind (self->inbox, "tcp://%s:*", iface);
            assert (self->port > 0);    //  Die on bad interface or port exhaustion

            char *hostname = zsys_hostname ();
            self->endpoint = zsys_sprintf ("tcp://%s:%d", hostname, self->port);
            zstr_free (&hostname);
        }
        assert (self->gossip);
        zstr_sendx (self->gossip, "PUBLISH", zuuid_str (self->uuid), self->endpoint, NULL);
        //  Start polling on zgossip
        zpoller_add (self->poller, self->gossip);
    }
    //  Start polling on inbox
    zpoller_add (self->poller, self->inbox);
    return 0;
}
예제 #18
0
파일: broker.c 프로젝트: emef/sprk
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;
    }
}
예제 #19
0
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;
}