Exemplo n.º 1
0
zmsg_t *
mdwrk_recv (mdwrk_t *self, zmsg_t *reply)
{
    //  Format and send the reply if we were provided one
    assert (reply || !self->expect_reply);
    if (reply) {
        zmsg_t *msg = zmsg_dup (reply);
        zmsg_push (msg, MDPS_REPLY);
        zmsg_push (msg, MDPS_HEADER);
        zmsg_send (&msg, self->worker);
    }
    self->expect_reply = 1;

    while (1) {
        zmq_pollitem_t items [] = { { self->worker,  0, ZMQ_POLLIN, 0 } };
        zmq_poll (items, 1, HEARTBEAT_INTERVAL * 1000);

        if (items [0].revents & ZMQ_POLLIN) {
            zmsg_t *msg = zmsg_recv (self->worker);
            self->liveness = HEARTBEAT_LIVENESS;

            //  Don't try to handle errors, just assert noisily
            assert (zmsg_parts (msg) >= 3);

            char *header = zmsg_pop (msg);
            assert (strcmp (header, MDPS_HEADER) == 0);
            free (header);

            char *command = zmsg_pop (msg);
            if (strcmp (command, MDPS_REQUEST) == 0)
                return msg;     //  We have a request to process
            else
            if (strcmp (command, MDPS_HEARTBEAT) == 0)
                ;               //  Do nothing for heartbeats
            else
            if (strcmp (command, MDPS_DISCONNECT) == 0)
                break;          //  Return empty handed
            else {
                printf ("E: invalid input message (%d)\n", (int) command [1]);
                zmsg_dump (msg);
            }
            free (command);
        }
        else
        if (--self->liveness == 0) {
            s_sleep (RECONNECT_INTERVAL);
            s_connect_to_broker (self);
        }
        //  Send HEARTBEAT if it's time
        if (s_clock () > self->heartbeat_at) {
            self->heartbeat_at = s_clock () + HEARTBEAT_INTERVAL;
            s_send (self->worker, "HEARTBEAT");
        }
    }
    //  We exit if we've been disconnected
    return NULL;
}
Exemplo n.º 2
0
void
clone_set (clone_t *self, char *key, char *value)
{
    assert (self);
    assert (endpoint);
    zmsg_t *msg = zmsg_new (value);
    zmsg_push (msg, key);
    zmsg_push (msg, "SET");
    zmsg_send (&msg, self->control);
}
Exemplo n.º 3
0
zmsg_t *
mdcli_send (mdcli_t *self, char *service, zmsg_t *request)
{
    int retries_left = REQUEST_RETRIES;
    while (retries_left) {
        //  Prefix request with protocol frames
        //  Frame 1: "MDPCxy" (six bytes, MDP/Client x.y)
        //  Frame 2: Service name (printable string)
        zmsg_t *msg = zmsg_dup (request);
        zmsg_push (msg, service);
        zmsg_push (msg, MDPC_HEADER);
        zmsg_send (&msg, self->client);

        while (1) {
            //  Poll socket for a reply, with timeout
            zmq_pollitem_t items [] = { { self->client, 0, ZMQ_POLLIN, 0 } };
            zmq_poll (items, 1, REQUEST_TIMEOUT * 1000);

            //  If we got a reply, process it
            if (items [0].revents & ZMQ_POLLIN) {
                zmsg_t *msg = zmsg_recv (self->client);

                //  Don't try to handle errors, just assert noisily
                assert (zmsg_parts (msg) >= 3);

                char *header = zmsg_pop (msg);
                assert (strcmp (header, MDPC_HEADER) == 0);
                free (header);

                char *service = zmsg_pop (msg);
                assert (strcmp (service, service) == 0);
                free (service);

                return msg;     //  Success
            }
            else
            if (--retries_left) {
                //  Reconnect, and resend message
                s_connect_to_broker (self);
                zmsg_t *msg = zmsg_dup (request);
                zmsg_push (msg, service);
                zmsg_push (msg, MDPC_HEADER);
                zmsg_send (&msg, self->client);
            }
            else
                break;          //  Give up
        }
    }
    return NULL;
}
Exemplo n.º 4
0
END_TEST


//  --------------------------------------------------------------------------
/// _pop () multiple times. Mainly used to test the garbage collection.
START_TEST(test_msg_pop_successively)
{
    sam_selftest_introduce ("test_msg_pop_successively");

    zmsg_t *zmsg = zmsg_new ();
    zmsg_pushstr (zmsg, "three");
    zmsg_pushstr (zmsg, "two");
    zmsg_pushstr (zmsg, "one");

    char payload = '0';
    zframe_t *frame = zframe_new (&payload, sizeof (payload));
    zmsg_push (zmsg, frame);

    sam_msg_t *msg = sam_msg_new (&zmsg);

    zframe_t *zero;
    char *one;

    int rc = sam_msg_pop (msg, "fs", &zero, &one);
    ck_assert_int_eq (rc, 0);
    ck_assert_int_eq (sam_msg_size (msg), 2);

    char *two, *three;
    rc = sam_msg_pop (msg, "ss", &two, &three);
    ck_assert_int_eq (rc, 0);
    ck_assert_int_eq (sam_msg_size (msg), 0);

    sam_msg_destroy (&msg);
}
Exemplo n.º 5
0
void 
agent_router_message (agent_t *self)
{
    zmsg_t *reply = zmsg_recv (self->router);

    //  Frame 0 is server that replied
    char *endpoint = zmsg_pop (reply);
    server_t *server = (server_t *) zhash_lookup (self->servers, endpoint);
    assert (server);
    free (endpoint);
    if (!server->alive) {
        zlist_append (self->actives, server);
        server->alive = 1;
    }
    server->ping_at = s_clock () + PING_INTERVAL;
    server->expires = s_clock () + SERVER_TTL;

    //  Frame 1 may be sequence number for reply
    if (zmsg_parts (reply) > 1
    &&  atoi (zmsg_address (reply)) == self->sequence) {
        free (zmsg_pop (reply));
        zmsg_push (reply, "OK");
        zmsg_send (&reply, self->control);
        zmsg_destroy (&self->request);
    }
    zmsg_destroy (&reply);
}
Exemplo n.º 6
0
void 
agent_control_message (agent_t *self)
{
    zmsg_t *msg = zmsg_recv (self->control);
    char *command = zmsg_pop (msg);

    if (strcmp (command, "CONNECT") == 0) {
        char *endpoint = zmsg_pop (msg);
        printf ("I: connecting to %s...\n", endpoint);
        int rc = zmq_connect (self->router, endpoint);
        assert (rc == 0);
        server_t *server = server_new (endpoint);
        zhash_insert (self->servers, endpoint, server);
        zhash_freefn (self->servers, endpoint, s_server_free);
        zlist_append (self->actives, server);
        server->ping_at = s_clock () + PING_INTERVAL;
        server->expires = s_clock () + SERVER_TTL;
        free (endpoint);
    }
    else
    if (strcmp (command, "REQUEST") == 0) {
        assert (!self->request);    //  Strict request-reply cycle
        //  Prefix request with sequence number and empty envelope
        char sequence_text [10];
        sprintf (sequence_text, "%u", ++self->sequence);
        zmsg_push (msg, sequence_text);
        //  Take ownership of request message
        self->request = msg;
        msg = NULL;
        //  Request expires after global timeout
        self->expires = s_clock () + GLOBAL_TIMEOUT;
    }
    free (command);
    zmsg_destroy (&msg);
}
Exemplo n.º 7
0
END_TEST


//  --------------------------------------------------------------------------
/// Try to _get () a zframe pointer.
START_TEST(test_msg_get_f)
{
    sam_selftest_introduce ("test_msg_get_f");

    zmsg_t *zmsg = zmsg_new ();
    char payload = 'a';
    zframe_t *frame = zframe_new (&payload, sizeof (payload));
    int rc = zmsg_push (zmsg, frame);
    ck_assert_int_eq (rc, 0);

    sam_msg_t *msg = sam_msg_new (&zmsg);
    ck_assert_int_eq (sam_msg_size (msg), 1);

    zframe_t *ref;
    rc = sam_msg_get (msg, "f", &ref);
    ck_assert_int_eq (rc, 0);
    ck_assert_int_eq (sam_msg_size (msg), 1);
    ck_assert (zframe_eq (ref, frame));
    zframe_destroy (&ref);

    // check idempotency of _get ()
    rc = sam_msg_get (msg, "f", &ref);
    ck_assert_int_eq (rc, 0);
    ck_assert_int_eq (sam_msg_size (msg), 1);
    ck_assert (zframe_eq (ref, frame));
    zframe_destroy (&ref);

    sam_msg_destroy (&msg);
}
Exemplo n.º 8
0
END_TEST


//  --------------------------------------------------------------------------
/// Try to _pop () a zframe pointer.
START_TEST(test_msg_pop_f)
{
    sam_selftest_introduce ("test_msg_pop_f");

    zmsg_t *zmsg = zmsg_new ();
    char payload = 'a';

    zframe_t
        *frame = zframe_new (&payload, sizeof (payload)),
        *ref = zframe_dup (frame);


    int rc = zmsg_push (zmsg, frame);
    ck_assert_int_eq (rc, 0);

    sam_msg_t *msg = sam_msg_new (&zmsg);
    ck_assert_int_eq (sam_msg_size (msg), 1);

    zframe_t *popped;
    rc = sam_msg_pop (msg, "f", &popped);

    ck_assert_int_eq (rc, 0);
    ck_assert (zframe_eq (ref, popped));
    ck_assert_int_eq (sam_msg_size (msg), 0);

    zframe_destroy (&ref);
    sam_msg_destroy (&msg);
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
Arquivo: zmsg.c Projeto: bumptech/czmq
void
zmsg_wrap (zmsg_t *self, zframe_t *frame)
{
    assert (self);
    assert (frame);
    if (zmsg_pushmem (self, "", 0) == 0)
        zmsg_push (self, frame);
}
Exemplo n.º 11
0
void
clone_connect (clone_t *self, char *address, int port)
{
    assert (self);
    assert (endpoint);
    zmsg_t *msg = zmsg_new (address);
    zmsg_push (msg, "CONNECT");
    zmsg_send (&msg, self->control);
}
Exemplo n.º 12
0
void
flcliapi_connect (flcliapi_t *self, char *endpoint)
{
    assert (self);
    assert (endpoint);
    zmsg_t *msg = zmsg_new (endpoint);
    zmsg_push (msg, "CONNECT");
    zmsg_send (&msg, self->control);
    s_sleep (100);      //  Allow connection to come up
}
Exemplo n.º 13
0
int main(int argc, char **argv)
{	
	zctx_t *ctx;
	zwssock_t *sock;

	char *l =  argc > 1 ? argv[1] : listen_on;

	int major, minor, patch;
	zmq_version (&major, &minor, &patch);
	printf("built with: ØMQ=%d.%d.%d czmq=%d.%d.%d\n",
	       major, minor, patch,
	       CZMQ_VERSION_MAJOR, CZMQ_VERSION_MINOR,CZMQ_VERSION_PATCH);


	ctx = zctx_new();
	sock = zwssock_new_router(ctx);

	zwssock_bind(sock, l);

	zmsg_t* msg;
	zframe_t *id;

	while (!zctx_interrupted)
	{		
		msg = zwssock_recv(sock);
		
		if (!msg)
			break;

		// first message is the routing id
		id = zmsg_pop(msg);

		while (zmsg_size(msg) != 0)
		{
			char * str = zmsg_popstr(msg);

			printf("%s\n", str);
			
			free(str);
		}

		zmsg_destroy(&msg);

		msg = zmsg_new();

		zmsg_push(msg, id);
		zmsg_addstr(msg, "hello back");

		zwssock_send(sock, &msg);
	}
	
	zwssock_destroy(&sock);
	zctx_destroy(&ctx);	
}
Exemplo n.º 14
0
void worker(void *args, zctx_t *ctx, void *pipe) {
	long mashine_number =  ((setting_t *) args)->mashine_number;
	long thread_number = ((setting_t *) args)->thread_number;	
	long auto_increment = 0;
    struct timeval tp;
	
	void *worker = zsocket_new(ctx, ZMQ_DEALER);
	zsocket_connect(worker, "inproc://zid");
	
	while (!zctx_interrupted) {
		zmsg_t *request = zmsg_recv(worker);
		
		/* drop message if its size is less than 2 */
		if (zmsg_size(request) != 2) {
			zmsg_destroy(&request);
			continue;
		}
		/* sender id */
		zframe_t *sender = zmsg_pop(request);
		
		/* number of id to generate */
		char *num = zmsg_popstr(request);
		int n = atoi(num);
		free(num);
		
		if (n > 0) {
		
			/* response message */
			zmsg_t *response = zmsg_new();
		
			int i;
			for (i = 0; i < n; i++) {
				gettimeofday(&tp, NULL);
			
				zmsg_addstrf(response, "%ld", ((mashine_number << 59) | (thread_number << 56) | (auto_increment << 45) | (tp.tv_sec << 10) | (tp.tv_usec / 1000)));
			
				auto_increment++;
				if (auto_increment == 2048) {
					auto_increment = 0;
				}
			}
		
			/* push sender id */
			zmsg_push(response, sender);
			/* send back reply */
			zmsg_send(&response, worker);
		} else {
			zframe_destroy(&sender);
		}
		
		zmsg_destroy(&request);
	}
}
Exemplo n.º 15
0
zmsg_t *utils_gen_msg(const char *device_id, const char *msgid, const char *msg, char *bytes, int len)
{
  zmsg_t *answer = zmsg_new();
  if (bytes != NULL) {
    zframe_t *frame = zframe_new (bytes, len);
    zmsg_push(answer, frame);
  }
  zmsg_pushstr(answer, "%s", msg);
  zmsg_pushstr(answer, "%s", msgid);
  zmsg_pushstr(answer, "%s", device_id);
  return answer;
}
Exemplo n.º 16
0
int
server_ping (char *key, void *server, void *socket)
{
    server_t *self = (server_t *) server;
    if (s_clock () >= self->ping_at) {
        zmsg_t *ping = zmsg_new ("PING");
        zmsg_push (ping, self->endpoint);
        zmsg_send (&ping, socket);
        self->ping_at = s_clock () + PING_INTERVAL;
    }
    return 0;
}
Exemplo n.º 17
0
int
mdcli_send (mdcli_t *self, char *service, zmsg_t **request_p)
{
    assert (self);
    assert (request_p);
    zmsg_t *request = *request_p;

    //  Prefix request with protocol frames
    //  Frame 0: empty (REQ emulation)
    //  Frame 1: "MDPCxy" (six bytes, MDP/Client x.y)
    //  Frame 2: Service name (printable string)
    zmsg_push (request, service);
    zmsg_push (request, MDPC_CLIENT);
    zmsg_push (request, "");
    if (self->verbose) {
        s_console ("I: send request to '%s' service:", service);
        zmsg_dump (request);
    }
    zmsg_send (&request, self->client);
    return 0;
}
Exemplo n.º 18
0
void SNetDistribZMQSend(zframe_t *payload, int type, int destination)
{
  int rc;
  zframe_t *source_f = NULL;
  zframe_t *type_f = NULL;
  zmsg_t *msg = zmsg_new();

  zmsg_push(msg, payload);

  SNetDistribPack(&type_f, &type, sizeof(int));
  zmsg_push(msg, type_f);

  SNetDistribPack(&source_f, &node_location, sizeof(int));
  zmsg_push(msg, source_f);

  rc = HTabSend(msg, destination);
  if (rc != 0) {
    SNetUtilDebugFatal("ZMQDistrib: Cannot send message to  %d (%s): zmsg_send (%d)",
        destination, SNetDistribZMQHTabLookUp(destination)->host, rc);
  }
}
Exemplo n.º 19
0
static void
s_worker_send (
    broker_t *self, worker_t *worker,
    char *command, char *option, zmsg_t *msg)
{
    msg = msg? zmsg_dup (msg): zmsg_new (NULL);

    //  Stack protocol envelope to start of message
    if (option)                 //  Optional frame after command
        zmsg_push (msg, option);
    zmsg_push (msg, command);
    zmsg_push (msg, MDPW_WORKER);
    //  Stack routing envelope to start of message
    zmsg_wrap (msg, worker->identity, "");

    if (self->verbose) {
        s_console ("I: sending %s to worker",
            mdps_commands [(int) *command]);
        zmsg_dump (msg);
    }
    zmsg_send (&msg, self->socket);
}
Exemplo n.º 20
0
zmsg_t *
flclient_request (flclient_t *self, zmsg_t **request_p)
{
    assert (self);
    assert (*request_p);
    zmsg_t *request = *request_p;
    
    //  Prefix request with sequence number and empty envelope
    char sequence_text [10];
    sprintf (sequence_text, "%u", ++self->sequence);
    zmsg_push (request, sequence_text);
    zmsg_push (request, "");
    
    //  Blast the request to all connected servers
    int server;
    for (server = 0; server < self->servers; server++) {
        zmsg_t *msg = zmsg_dup (request);
        zmsg_send (&msg, self->socket);
    }
    //  Wait for a matching reply to arrive from anywhere
    //  Since we can poll several times, calculate each one
    zmsg_t *reply = NULL;
    uint64_t endtime = s_clock () + GLOBAL_TIMEOUT;
    while (s_clock () < endtime) {
        zmq_pollitem_t items [] = { { self->socket, 0, ZMQ_POLLIN, 0 } };
        zmq_poll (items, 1, (endtime - s_clock ()) * 1000);
        if (items [0].revents & ZMQ_POLLIN) {
            reply = zmsg_recv (self->socket);
            assert (zmsg_parts (reply) == 3);
            free (zmsg_pop (reply));
            if (atoi (zmsg_address (reply)) == self->sequence)
                break;
            zmsg_destroy (&reply);
        }
    }
    zmsg_destroy (request_p);
    return reply;
}
Exemplo n.º 21
0
Arquivo: broker.c Projeto: tnako/DP
static void s_broker_client_msg(broker_t *self, zframe_t *sender, zmsg_t *msg)
{
    assert (zmsg_size(msg) >= 2);     //  Service name + body

    zframe_t *service_frame = zmsg_pop(msg);
    service_t *service = s_service_require(self, service_frame);
 // Не должен создавать сервис, в случаи запроса от клиента

    //  Set reply return identity to client sender
    zmsg_wrap(msg, zframe_dup(sender));

    //  If we got a MMI service request, process that internally
    if (zframe_size(service_frame) >= 4 &&  memcmp(zframe_data(service_frame), "mmi.", 4) == 0) {
        char *return_code;
		
        if (zframe_streq(service_frame, "mmi.service")) {
            char *name = zframe_strdup (zmsg_last (msg));
            service_t *service = (service_t *) zhash_lookup(self->services, name);
			if (service) {
			  if (service->workers) {
				return_code = "200";
			  } else {
				return_code = "404";
			  }
			} else {
			  return_code = "401";
			}
            free(name);
        } else {
            return_code = "501";
		}

        zframe_reset(zmsg_last(msg), return_code, strlen(return_code));

        //  Remove & save client return envelope and insert the
        //  protocol header and service name, then rewrap envelope.
        zframe_t *client = zmsg_unwrap (msg);
        zmsg_push(msg, zframe_dup(service_frame));
        zmsg_pushstr(msg, MDPC_CLIENT);
        zmsg_wrap(msg, client);
        zmsg_send(&msg, self->socket);
    } else {
        //  Else dispatch the message to the requested service
        s_service_dispatch(service, msg);
	}
	
    zframe_destroy(&service_frame);
}
Exemplo n.º 22
0
zmsg_t *
flcliapi_request (flcliapi_t *self, zmsg_t **request_p)
{
    assert (self);
    assert (*request_p);

    zmsg_push (*request_p, "REQUEST");
    zmsg_send (request_p, self->control);
    zmsg_t *reply = zmsg_recv (self->control);
    if (reply) {
        char *status = zmsg_pop (reply);
        if (strcmp (status, "FAILED") == 0)
            zmsg_destroy (&reply);
        free (status);
    }
    return reply;
}
Exemplo n.º 23
0
char *
clone_get (clone_t *self, char *key)
{
    assert (self);
    assert (endpoint);
    zmsg_t *msg = zmsg_new (key);
    zmsg_push (msg, "GET");
    zmsg_send (&msg, self->control);

    zmsg_t *reply = zmsg_recv (self->control);
    if (reply) {
        char *value = zmsg_pop (reply);
        zmsg_destroy (&reply);
        return value;
    }
    return NULL;
}
Exemplo n.º 24
0
int main (int argc, char *argv [])
{
    int verbose = (argc > 1 && streq (argv [1], "-v"));

    zctx_t *ctx = zctx_new ();

    //  Prepare server socket with predictable identity
    char *bind_endpoint = "tcp://*:5555";
    char *connect_endpoint = "tcp://localhost:5555";
    void *server = zsocket_new (ctx, ZMQ_ROUTER);
    zmq_setsockopt (server,
        ZMQ_IDENTITY, connect_endpoint, strlen (connect_endpoint));
    zsocket_bind (server, bind_endpoint);
    printf ("I: service is ready at %s\n", bind_endpoint);

    while (!zctx_interrupted) {
        zmsg_t *request = zmsg_recv (server);
        if (verbose && request)
            zmsg_dump (request);
        if (!request)
            break;          //  Interrupted

        //  Frame 0: identity of client
        //  Frame 1: PING, or client control frame
        //  Frame 2: request body
        zframe_t *identity = zmsg_pop (request);
        zframe_t *control = zmsg_pop (request);
        zmsg_t *reply = zmsg_new ();
        if (zframe_streq (control, "PING"))
            zmsg_addstr (reply, "PONG");
        else {
            zmsg_add (reply, control);
            zmsg_addstr (reply, "OK");
        }
        zmsg_destroy (&request);
        zmsg_push (reply, identity);
        if (verbose && reply)
            zmsg_dump (reply);
        zmsg_send (&reply, server);
    }
    if (zctx_interrupted)
        printf ("W: interrupted\n");

    zctx_destroy (&ctx);
    return 0;
}
Exemplo n.º 25
0
zlist_t * fetch_rules(void * sock, char * channel) {

  zlist_t * rules = zlist_new();
  /*  if(!endpoint) {
    zclock_log("W: no reup endpoint defined, won't try te refresh rules");
    return rules;
    }*/
  // zsocket_connect(sock, endpoint);
  zstr_sendm(sock, "");
  zstr_send(sock, channel);
  zmsg_t * tmp; 
  //   while(tmp=zmsg_recv(sock)) { 
     //     zmsg_dump(tmp); 
  //} 
  // exit(1); 

  zmsg_t * msg = zmsg_recv(sock);
  kill_envelope(msg);
  char * status = zmsg_popstr(msg);
  if(strcmp("200", status) != 0) {
    zclock_log("W: reloading rules for %s failed: got |%s|", channel, status);
    return rules;
  }
  free(status);
  zmsg_destroy(&msg);
  
  while((msg=zmsg_recv(sock))) {
    zclock_log("once");
    kill_envelope(msg);
    zmsg_dump(msg);
    zframe_t * header = zmsg_pop(msg);
    if(zframe_streq(header, "")) {
      // we're done
      zclock_log("got a null header, we're out");
      zframe_destroy(&header);
      zmsg_destroy(&msg);
      break;
    }
    zmsg_push(msg, header);
    zlist_push(rules, msg);
  }
  return rules;

}
Exemplo n.º 26
0
int main (int argc, char *argv [])
{
    int verbose = (argc > 1 && streq (argv [1], "-v"));
    mdcli_t *session = mdcli_new ("tcp://localhost:5555", verbose);

    //  1. Send 'echo' request to Titanic
    zmsg_t *request = zmsg_new ("Hello world");
    zmsg_push (request, "echo");
    zmsg_t *reply = s_service_call (
        session, "titanic.request", &request);
    char *uuid = NULL;
    if (reply) {
        uuid = zmsg_pop (reply);
        zmsg_destroy (&reply);
        printf ("I: request UUID: %s\n", uuid);
    }

    //  2. Wait until we get a reply
    while (!s_interrupted) {
        s_sleep (100);
        request = zmsg_new (uuid);
        zmsg_t *reply = s_service_call (
            session, "titanic.reply", &request);
        if (reply) {
            printf ("Reply: %s\n", zmsg_body (reply));
            zmsg_destroy (&reply);

            //  3. Close request
            request = zmsg_new (uuid);
            reply = s_service_call (session, "titanic.close", &request);
            zmsg_destroy (&reply);
            break;
        }
        else {
            printf ("I: no reply yet, trying again...\n");
            s_sleep (5000);     //  Try again in 5 seconds
        }
    }
    mdcli_destroy (&session);
    return 0;
}
Exemplo n.º 27
0
static void
s_service_internal (broker_t *self, zframe_t *service_frame, zmsg_t *msg)
{
    char *return_code;
    if (zframe_streq (service_frame, "mmi.service")) {
        char *name = zframe_strdup (zmsg_last (msg));
        service_t *service =
            (service_t *) zhash_lookup (self->services, name);
        return_code = service && service->workers? "200": "404";
        free (name);
    }
    else
        return_code = "501";

    zframe_reset (zmsg_last (msg), return_code, strlen (return_code));

    //  Remove & save client return envelope and insert the
    //  protocol header and service name, then rewrap envelope.
    zframe_t *client = zmsg_unwrap (msg);
    zmsg_push (msg, zframe_dup (service_frame));
    zmsg_pushstr (msg, MDPC_CLIENT);
    zmsg_wrap (msg, client);
    zmsg_send (&msg, self->socket);
}
Exemplo n.º 28
0
int main(void)
{
	zctx_t *ctx = zctx_new();
	void *frontend = zsocket_new(ctx, ZMQ_ROUTER);
	void *backend = zsocket_new(ctx, ZMQ_ROUTER);

	// IPC doesn't yet work on MS Windows.
#if (defined (WIN32))
	zsocket_bind(frontend, "tcp://*:5672");
	zsocket_bind(backend, "tcp://*:5673");
#else
	zsocket_bind(frontend, "ipc://frontend.ipc");
	zsocket_bind(backend, "ipc://backend.ipc");
#endif

	int client_nbr;
	for (client_nbr = 0; client_nbr < NBR_CLIENTS; client_nbr++)
		zthread_new(client_task, NULL);
	int worker_nbr;
	for (worker_nbr = 0; worker_nbr < NBR_WORKERS; worker_nbr++)
		zthread_new(worker_task, NULL);

	//  Queue of available workers
	zlist_t *workers = zlist_new();

	//  .split main load-balancer loop
	//  Here is the main loop for the load balancer. It works the same way
	//  as the previous example, but is a lot shorter because CZMQ gives
	//  us an API that does more with fewer calls:
	while (1) {
		zmq_pollitem_t items[] = {
				{ backend, 0, ZMQ_POLLIN, 0 },
				{ frontend, 0, ZMQ_POLLIN, 0 }
		};
		//  Poll frontend only if we have available workers
		int rc = zmq_poll(items, zlist_size(workers) ? 2 : 1, -1);
		if (rc == -1)
			break;              //  Interrupted

		//  Handle worker activity on backend
		if (items[0].revents & ZMQ_POLLIN) {
			//  Use worker identity for load-balancing
			zmsg_t *msg = zmsg_recv(backend);
			if (!msg)
				break;          //  Interrupted

#if 0
			// zmsg_unwrap is DEPRECATED as over-engineered, poor style
			zframe_t *identity = zmsg_unwrap(msg);
#else
			zframe_t *identity = zmsg_pop(msg);
			zframe_t *delimiter = zmsg_pop(msg);
			zframe_destroy(&delimiter); 
#endif

			zlist_append(workers, identity);

			//  Forward message to client if it's not a READY
			zframe_t *frame = zmsg_first(msg);
			if (memcmp(zframe_data(frame), WORKER_READY, strlen(WORKER_READY)) == 0) {
				zmsg_destroy(&msg);
			} else {
				zmsg_send(&msg, frontend);
				if (--client_nbr == 0)
					break; // Exit after N messages
			}
		}
		if (items[1].revents & ZMQ_POLLIN) {
			//  Get client request, route to first available worker
			zmsg_t *msg = zmsg_recv(frontend);
			if (msg) {
#if 0
				// zmsg_wrap is DEPRECATED as unsafe
				zmsg_wrap(msg, (zframe_t *)zlist_pop(workers));
#else
				zmsg_pushmem(msg, NULL, 0); // delimiter
				zmsg_push(msg, (zframe_t *)zlist_pop(workers));
#endif

				zmsg_send(&msg, backend);
			}
		}
	}
	//  When we're done, clean up properly
	while (zlist_size(workers)) {
		zframe_t *frame = (zframe_t *)zlist_pop(workers);
		zframe_destroy(&frame);
	}
	zlist_destroy(&workers);
	zctx_destroy(&ctx);
	return 0;
}
Exemplo n.º 29
0
int main (void)
{
    zctx_t *ctx = zctx_new ();
    void *frontend = zsocket_new (ctx, ZMQ_ROUTER);
    void *backend = zsocket_new (ctx, ZMQ_ROUTER);
    zsocket_bind (frontend, "tcp://*:5555");    //  For clients
    zsocket_bind (backend,  "tcp://*:5556");    //  For workers

    //  List of available workers
    zlist_t *workers = zlist_new ();

    //  Send out heartbeats at regular intervals
    uint64_t heartbeat_at = zclock_time () + HEARTBEAT_INTERVAL;

    while (1) {
        zmq_pollitem_t items [] = {
            { backend,  0, ZMQ_POLLIN, 0 },
            { frontend, 0, ZMQ_POLLIN, 0 }
        };
        //  Poll frontend only if we have available workers
        int rc = zmq_poll (items, zlist_size (workers)? 2: 1,
            HEARTBEAT_INTERVAL * ZMQ_POLL_MSEC);
        if (rc == -1)
            break;              //  Interrupted

        //  Handle worker activity on backend
        if (items [0].revents & ZMQ_POLLIN) {
            //  Use worker address for LRU routing
            zmsg_t *msg = zmsg_recv (backend);
            if (!msg)
                break;          //  Interrupted

            //  Any sign of life from worker means it's ready
            zframe_t *address = zmsg_unwrap (msg);
            worker_t *worker = s_worker_new (address);
            s_worker_ready (worker, workers);

            //  Validate control message, or return reply to client
            if (zmsg_size (msg) == 1) {
                zframe_t *frame = zmsg_first (msg);
                if (memcmp (zframe_data (frame), PPP_READY, 1)
                &&  memcmp (zframe_data (frame), PPP_HEARTBEAT, 1)) {
                    printf ("E: invalid message from worker");
                    zmsg_dump (msg);
                }
                zmsg_destroy (&msg);
            }
            else
                zmsg_send (&msg, frontend);
        }
        if (items [1].revents & ZMQ_POLLIN) {
            //  Now get next client request, route to next worker
            zmsg_t *msg = zmsg_recv (frontend);
            if (!msg)
                break;          //  Interrupted
            zmsg_push (msg, s_workers_next (workers));
            zmsg_send (&msg, backend);
        }

        //  .split handle heartbeating
        //  We handle heartbeating after any socket activity. First we send
        //  heartbeats to any idle workers if it's time. Then we purge any
        //  dead workers:
        
        if (zclock_time () >= heartbeat_at) {
            worker_t *worker = (worker_t *) zlist_first (workers);
            while (worker) {
                zframe_send (&worker->address, backend,
                             ZFRAME_REUSE + ZFRAME_MORE);
                zframe_t *frame = zframe_new (PPP_HEARTBEAT, 1);
                zframe_send (&frame, backend, 0);
                worker = (worker_t *) zlist_next (workers);
            }
            heartbeat_at = zclock_time () + HEARTBEAT_INTERVAL;
        }
        s_workers_purge (workers);
    }

    //  When we're done, clean up properly
    while (zlist_size (workers)) {
        worker_t *worker = (worker_t *) zlist_pop (workers);
        s_worker_destroy (&worker);
    }
    zlist_destroy (&workers);
    zctx_destroy (&ctx);
    return 0;
}
Exemplo n.º 30
0
zmsg_t *
mdcli_send (mdcli_t *self, char *service, zmsg_t **request_p)
{
    assert (self);
    assert (request_p);
    zmsg_t *request = *request_p;

    //  Prefix request with protocol frames
    //  Frame 1: "MDPCxy" (six bytes, MDP/Client x.y)
    //  Frame 2: Service name (printable string)
    zmsg_push (request, service);
    zmsg_push (request, MDPC_CLIENT);
    if (self->verbose) {
        s_console ("I: send request to '%s' service:", service);
        zmsg_dump (request);
    }

    int retries_left = self->retries;
    while (retries_left && !s_interrupted) {
        zmsg_t *msg = zmsg_dup (request);
        zmsg_send (&msg, self->client);

        while (!s_interrupted) {
            //  Poll socket for a reply, with timeout
            zmq_pollitem_t items [] = { 
                { self->client, 0, ZMQ_POLLIN, 0 } };
            zmq_poll (items, 1, self->timeout * 1000);

            //  If we got a reply, process it
            if (items [0].revents & ZMQ_POLLIN) {
                zmsg_t *msg = zmsg_recv (self->client);
                if (self->verbose) {
                    s_console ("I: received reply:");
                    zmsg_dump (msg);
                }
                //  Don't try to handle errors, just assert noisily
                assert (zmsg_parts (msg) >= 3);

                char *header = zmsg_pop (msg);
                assert (streq (header, MDPC_CLIENT));
                free (header);

                char *reply_service = zmsg_pop (msg);
                assert (streq (reply_service, service));
                free (reply_service);

                zmsg_destroy (&request);
                return msg;     //  Success
            }
            else
            if (--retries_left) {
                if (self->verbose)
                    s_console ("W: no reply, reconnecting...");
                //  Reconnect, and resend message
                s_mdcli_connect_to_broker (self);
                zmsg_t *msg = zmsg_dup (request);
                zmsg_send (&msg, self->client);
            }
            else {
                if (self->verbose)
                    s_console ("W: permanent error, abandoning request");
                break;          //  Give up
            }
        }
    }
    if (s_interrupted)
        printf ("W: interrupt received, killing client...\n");
    zmsg_destroy (&request);
    return NULL;
}