void WorkerAgent::actorTask(zsock_t *pipe, void *args)
{
    assert(pipe);
    assert(args);

    const WorkerAgent &agent = *static_cast<WorkerAgent *>(args);

    const auto worker = detail::makeSock(zsock_new_router(agent._localEndpoint.c_str()));
    assert(worker.get());

    const auto poller = detail::makePoller(zpoller_new(pipe, worker.get(), nullptr));
    assert(poller.get());

    int rc = zsock_signal(pipe, 0);
    UNUSED(rc);
    assert(rc == 0);

    bool terminated = false;
    while (!terminated && !zsys_interrupted) {
        zsock_t *sock = static_cast<zsock_t *>(zpoller_wait(poller.get(), -1));

        if (sock == pipe) {
            std::unique_ptr<char> command(zstr_recv(sock));
            if (streq(command.get(), "$TERM")) {
                terminated = true;
            }
        } else if (sock == worker.get()) {
            auto request = detail::makeMsg(zmsg_recv(sock));
            assert(zmsg_size(request.get()) == 3);

            auto identity = detail::makeFrame(zmsg_pop(request.get()));
            auto id = detail::makeFrame(zmsg_pop(request.get()));

            static const auto respond = [](
                                            auto &&identity,
                                            auto &&id,
                                            const char *status,
                                            auto &&data,
            zsock_t *sock) {
                zmsg_t *response = zmsg_new();

                // Identity for ROUTER
                zframe_t *f = identity.release();
                zmsg_append(response, &f);

                // Caller local ID
                f = id.release();
                zmsg_append(response, &f);

                // Status
                f = zframe_new(status, std::strlen(status));
                zmsg_append(response, &f);

                // Result
                f = data.release();
                zmsg_append(response, &f);

                zmsg_send(&response, sock);
            };

            try {
                auto argsFrame = detail::makeFrame(zmsg_pop(request.get()));

                msgpack::unpacked msg;
                msgpack::unpack(
                    &msg,
                    reinterpret_cast<const char *>(zframe_data(argsFrame.get())),
                    zframe_size(argsFrame.get()));

                msgpack::sbuffer sbuf;
                agent._callback(msg, sbuf);

                auto resultFrame =
                    detail::makeFrame(zframe_new(sbuf.data(), sbuf.size()));

                respond(identity, id, "", resultFrame, sock);
            } catch (const msgpack::type_error &e) {
                respond(identity, id, "I", detail::makeFrame(zframe_new_empty()), sock);
            } catch (const InvalidArgument &e) {
                respond(identity, id, "I", detail::makeFrame(zframe_new_empty()), sock);
            } catch (const UndefinedReference &e) {
                respond(identity, id, "U", detail::makeFrame(zframe_new_empty()), sock);
            } catch (const NetworkError &e) {
                respond(identity, id, "N", detail::makeFrame(zframe_new_empty()), sock);
            } catch (...) {
                respond(identity, id, "?", detail::makeFrame(zframe_new_empty()), sock);
            }
        }
    }

    zsys_debug("Cleaned up worker agent.");
}
Beispiel #2
0
///
//  Remove first frame from message, if any. Returns frame, or NULL.
QZframe * QZmsg::pop ()
{
    QZframe *rv = new QZframe (zmsg_pop (self));
    return rv;
}
Beispiel #3
0
Datei: zmsg.c Projekt: claws/czmq
void
zmsg_test (bool verbose)
{
    printf (" * zmsg: ");

    int rc = 0;
    //  @selftest
    //  Create two PAIR sockets and connect over inproc
    zsock_t *output = zsock_new_pair ("@inproc://zmsg.test");
    assert (output);
    zsock_t *input = zsock_new_pair (">inproc://zmsg.test");
    assert (input);

    //  Test send and receive of single-frame message
    zmsg_t *msg = zmsg_new ();
    assert (msg);
    zframe_t *frame = zframe_new ("Hello", 5);
    assert (frame);
    zmsg_prepend (msg, &frame);
    assert (zmsg_size (msg) == 1);
    assert (zmsg_content_size (msg) == 5);
    rc = zmsg_send (&msg, output);
    assert (msg == NULL);
    assert (rc == 0);

    msg = zmsg_recv (input);
    assert (msg);
    assert (zmsg_size (msg) == 1);
    assert (zmsg_content_size (msg) == 5);
    zmsg_destroy (&msg);

    //  Test send and receive of multi-frame message
    msg = zmsg_new ();
    assert (msg);
    rc = zmsg_addmem (msg, "Frame0", 6);
    assert (rc == 0);
    rc = zmsg_addmem (msg, "Frame1", 6);
    assert (rc == 0);
    rc = zmsg_addmem (msg, "Frame2", 6);
    assert (rc == 0);
    rc = zmsg_addmem (msg, "Frame3", 6);
    assert (rc == 0);
    rc = zmsg_addmem (msg, "Frame4", 6);
    assert (rc == 0);
    rc = zmsg_addmem (msg, "Frame5", 6);
    assert (rc == 0);
    rc = zmsg_addmem (msg, "Frame6", 6);
    assert (rc == 0);
    rc = zmsg_addmem (msg, "Frame7", 6);
    assert (rc == 0);
    rc = zmsg_addmem (msg, "Frame8", 6);
    assert (rc == 0);
    rc = zmsg_addmem (msg, "Frame9", 6);
    assert (rc == 0);
    zmsg_t *copy = zmsg_dup (msg);
    assert (copy);
    rc = zmsg_send (&copy, output);
    assert (rc == 0);
    rc = zmsg_send (&msg, output);
    assert (rc == 0);

    copy = zmsg_recv (input);
    assert (copy);
    assert (zmsg_size (copy) == 10);
    assert (zmsg_content_size (copy) == 60);
    zmsg_destroy (&copy);

    msg = zmsg_recv (input);
    assert (msg);
    assert (zmsg_size (msg) == 10);
    assert (zmsg_content_size (msg) == 60);

    // create empty file for null test
    FILE *file = fopen ("zmsg.test", "w");
    assert (file);
    fclose (file);

    file = fopen ("zmsg.test", "r");
    zmsg_t *null_msg = zmsg_load (NULL, file);
    assert (null_msg == NULL);
    fclose (file);
    remove ("zmsg.test");

    //  Save to a file, read back
    file = fopen ("zmsg.test", "w");
    assert (file);
    rc = zmsg_save (msg, file);
    assert (rc == 0);
    fclose (file);

    file = fopen ("zmsg.test", "r");
    rc = zmsg_save (msg, file);
    assert (rc == -1);
    fclose (file);
    zmsg_destroy (&msg);

    file = fopen ("zmsg.test", "r");
    msg = zmsg_load (NULL, file);
    assert (msg);
    fclose (file);
    remove ("zmsg.test");
    assert (zmsg_size (msg) == 10);
    assert (zmsg_content_size (msg) == 60);

    //  Remove all frames except first and last
    int frame_nbr;
    for (frame_nbr = 0; frame_nbr < 8; frame_nbr++) {
        zmsg_first (msg);
        frame = zmsg_next (msg);
        zmsg_remove (msg, frame);
        zframe_destroy (&frame);
    }
    //  Test message frame manipulation
    assert (zmsg_size (msg) == 2);
    frame = zmsg_last (msg);
    assert (zframe_streq (frame, "Frame9"));
    assert (zmsg_content_size (msg) == 12);
    frame = zframe_new ("Address", 7);
    assert (frame);
    zmsg_prepend (msg, &frame);
    assert (zmsg_size (msg) == 3);
    rc = zmsg_addstr (msg, "Body");
    assert (rc == 0);
    assert (zmsg_size (msg) == 4);
    frame = zmsg_pop (msg);
    zframe_destroy (&frame);
    assert (zmsg_size (msg) == 3);
    char *body = zmsg_popstr (msg);
    assert (streq (body, "Frame0"));
    free (body);
    zmsg_destroy (&msg);

    //  Test encoding/decoding
    msg = zmsg_new ();
    assert (msg);
    byte *blank = (byte *) zmalloc (100000);
    assert (blank);
    rc = zmsg_addmem (msg, blank, 0);
    assert (rc == 0);
    rc = zmsg_addmem (msg, blank, 1);
    assert (rc == 0);
    rc = zmsg_addmem (msg, blank, 253);
    assert (rc == 0);
    rc = zmsg_addmem (msg, blank, 254);
    assert (rc == 0);
    rc = zmsg_addmem (msg, blank, 255);
    assert (rc == 0);
    rc = zmsg_addmem (msg, blank, 256);
    assert (rc == 0);
    rc = zmsg_addmem (msg, blank, 65535);
    assert (rc == 0);
    rc = zmsg_addmem (msg, blank, 65536);
    assert (rc == 0);
    rc = zmsg_addmem (msg, blank, 65537);
    assert (rc == 0);
    free (blank);
    assert (zmsg_size (msg) == 9);
    byte *buffer;
    size_t buffer_size = zmsg_encode (msg, &buffer);
    zmsg_destroy (&msg);
    msg = zmsg_decode (buffer, buffer_size);
    assert (msg);
    free (buffer);
    zmsg_destroy (&msg);

    //  Test submessages
    msg = zmsg_new ();
    assert (msg);
    zmsg_t *submsg = zmsg_new ();
    zmsg_pushstr (msg, "matr");
    zmsg_pushstr (submsg, "joska");
    rc = zmsg_addmsg (msg, &submsg);
    assert (rc == 0);
    assert (submsg == NULL);
    submsg = zmsg_popmsg (msg);
    assert (submsg == NULL);   // string "matr" is not encoded zmsg_t, so was discarded
    submsg = zmsg_popmsg (msg);
    assert (submsg);
    body = zmsg_popstr (submsg);
    assert (streq (body, "joska"));
    free (body);
    zmsg_destroy (&submsg);
    frame = zmsg_pop (msg);
    assert (frame == NULL);
    zmsg_destroy (&msg);

    //  Test comparison of two messages
    msg = zmsg_new ();
    zmsg_addstr (msg, "One");
    zmsg_addstr (msg, "Two");
    zmsg_addstr (msg, "Three");
    zmsg_t *msg_other = zmsg_new ();
    zmsg_addstr (msg_other, "One");
    zmsg_addstr (msg_other, "Two");
    zmsg_addstr (msg_other, "One-Hundred");
    zmsg_t *msg_dup = zmsg_dup (msg);
    zmsg_t *empty_msg = zmsg_new ();
    zmsg_t *empty_msg_2 = zmsg_new ();
    assert (zmsg_eq (msg, msg_dup));
    assert (!zmsg_eq (msg, msg_other));
    assert (zmsg_eq (empty_msg, empty_msg_2));
    assert (!zmsg_eq (msg, NULL));
    assert (!zmsg_eq (NULL, empty_msg));
    assert (!zmsg_eq (NULL, NULL));
    zmsg_destroy (&msg);
    zmsg_destroy (&msg_other);
    zmsg_destroy (&msg_dup);
    zmsg_destroy (&empty_msg);
    zmsg_destroy (&empty_msg_2);

    //  Test signal messages
    msg = zmsg_new_signal (0);
    assert (zmsg_signal (msg) == 0);
    zmsg_destroy (&msg);
    msg = zmsg_new_signal (-1);
    assert (zmsg_signal (msg) == 255);
    zmsg_destroy (&msg);

    //  Now try methods on an empty message
    msg = zmsg_new ();
    assert (msg);
    assert (zmsg_size (msg) == 0);
    assert (zmsg_unwrap (msg) == NULL);
    assert (zmsg_first (msg) == NULL);
    assert (zmsg_last (msg) == NULL);
    assert (zmsg_next (msg) == NULL);
    assert (zmsg_pop (msg) == NULL);
    //  Sending an empty message is valid and destroys the message
    assert (zmsg_send (&msg, output) == 0);
    assert (!msg);

    zsock_destroy (&input);
    zsock_destroy (&output);

    //  @end
    printf ("OK\n");
}
Beispiel #4
0
///
//  Remove first frame from message, if any. Returns frame, or NULL.
QmlZframe *QmlZmsg::pop () {
    QmlZframe *retQ_ = new QmlZframe ();
    retQ_->self = zmsg_pop (self);
    return retQ_;
};
int
main (int argc, char *argv[])
{

    if (argc != 4) {
        exit (-1);
    }

    int numb_msgs = atoi (argv[2]);
    int numb_unimp_threads = atoi (argv[3]);

    zctx_t *ctx = zctx_new ();

    void *router_imp = zsocket_new (ctx, ZMQ_ROUTER);
    zsocket_set_rcvhwm (router_imp, 500000000);
    zsocket_bind (router_imp, "%s:9000", argv[1]);

    void *router_unimp = zsocket_new (ctx, ZMQ_ROUTER);
    zsocket_set_rcvhwm (router_unimp, 500000000);
    zsocket_bind (router_unimp, "%s:9001", argv[1]);

    void *pub = zsocket_new (ctx, ZMQ_PUB);
    zsocket_bind (pub, "%s:9002", argv[1]);


    int64_t time[3];

    int64_t idle=0;
    int64_t diff;


    zclock_sleep (1000);

//send the signal to start
    zmsg_t *amsg = zmsg_new ();
    zmsg_add (amsg, zframe_new ("all", 4));
    zmsg_send (&amsg, pub);

    zmq_pollitem_t pollitem[2] = { {router_imp, 0, ZMQ_POLLIN}
    , {router_unimp, 0, ZMQ_POLLIN}
    };
    unsigned long av_dropped_priority=0;
    unsigned long dropped=0;
    unsigned long av_processed_priority=0;
    unsigned long processed=0;
    int i;
    int imp_counter = 0;
    int once = 1;
    int ndiffs = 0;
    unsigned char drop_priority = 0;
    for (i = 0; i < 2 * numb_msgs; i++) {
        diff = zclock_time ();
        if (zmq_poll (pollitem, 2, -1) == -1) {
            exit (-1);
        }

        diff = zclock_time () - diff;
        idle = idle + diff;

update_drop_rate(&diff,&drop_priority,&ndiffs);


        if (pollitem[0].revents & ZMQ_POLLIN) {
            zmsg_t *msg = zmsg_recv (router_imp);
            if (!msg) {
                exit (-1);
            }
            zmsg_destroy (&msg);
            imp_counter++;
            if (imp_counter == numb_msgs) {
                time[0] = zclock_time ();
            }

        }
        else {

            if (pollitem[1].revents & ZMQ_POLLIN) {
                if (once) {
                    time[1] = zclock_time ();
                    once = 0;
                }
                zmsg_t *msg = zmsg_recv (router_unimp);
                if (!msg) {
                    exit (-1);
                }
                zframe_t *frame = zmsg_unwrap (msg);
                zframe_destroy (&frame);
                unsigned char priority;
                memcpy (&priority, zframe_data (zmsg_first (msg)), 1);
                if (priority < drop_priority) {
                    av_dropped_priority+=priority;
                    dropped++;
                 // printf ("dropped:%u\n", priority);
                    zmsg_destroy (&msg);
                }
                else {
                    av_processed_priority+=priority;
                    processed++;
                 //   printf ("received:%u\n", priority);
                    zmsg_destroy (&msg);
                }


            }
        }


    }
    time[2] = zclock_time ();
    printf ("msgs received:%d\n", i);

    amsg = zmsg_new ();
    zmsg_add (amsg, zframe_new ("all", 4));
    zmsg_send (&amsg, pub);


    zmsg_t *msg = zmsg_recv (router_imp);
    zframe_t *frame = zmsg_unwrap (msg);
    zframe_destroy (&frame);
    int64_t time_imp[2];
    frame = zmsg_pop (msg);
    memcpy (time_imp, zframe_data (frame), zframe_size (frame));
    zframe_destroy (&frame);
    zmsg_destroy (&msg);


    int64_t time_unimp[numb_unimp_threads][2];
for(i=0; i<numb_unimp_threads; i++){
   
     msg = zmsg_recv (router_unimp);
    frame = zmsg_unwrap (msg);
    zframe_destroy (&frame);
    frame = zmsg_pop (msg);
    memcpy (time_unimp[i], zframe_data (frame), zframe_size (frame));
    zframe_destroy (&frame);
    zmsg_destroy (&msg);

}


//compute average latency

    printf ("\nTime when important msgs started to be sent: %lld\n",
            time_imp[0]);
    printf ("\nTime when important msgs were processed: %lld\n", time[0]);
    printf ("\nDifference: %lld\n", time[0] - time_imp[0]);

for(i=0; i<numb_unimp_threads; i++){
    printf ("\nTime when unimportant msgs started to be sent: %lld\n",
            time_unimp[i][0]);
    printf ("\nTime when unimportant msgs were processed: %lld\n", time[2]);
    printf ("\nDifference: %lld\n", time[2] - time_unimp[i][0]);


}

    printf ("\nTime when unimportant msgs started to be processed: %lld\n",
            time[1]);


    printf ("idle time:%llu\n",idle);

    printf ("dropped msgs:%llu\n",dropped);
    printf ("av_dropped_priority:%llu\n",av_dropped_priority/dropped);
    printf ("processed msgs:%llu\n",processed);
    printf ("av_processed_priority:%llu\n",av_processed_priority/processed);


}
Beispiel #6
0
zmsg_t *
mdp_client_send (mdp_client_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_pushstr (request, service);
    zmsg_pushstr (request, MDPC_CLIENT);
    if (self->verbose) {
        zclock_log ("I: send request to '%s' service:", service);
        zmsg_dump (request);
    }
    int retries_left = self->retries;
    while (retries_left && !zctx_interrupted) {
        zmsg_t *msg = zmsg_dup (request);
        zmsg_send (&msg, self->client);

        zmq_pollitem_t items [] = {
            { self->client, 0, ZMQ_POLLIN, 0 }
        };
        //  On any blocking call, libzmq will return -1 if there was
        //  an error; we could in theory check for different error codes
        //  but in practice it's OK to assume it was EINTR (Ctrl-C)
        int rc = zmq_poll (items, 1, self->timeout * ZMQ_POLL_MSEC);
        if (rc == -1)
            break;          //  Interrupted

        //  If we got a reply, process it
        if (items [0].revents & ZMQ_POLLIN) {
            zmsg_t *msg = zmsg_recv (self->client);
            if (self->verbose) {
                zclock_log ("I: received reply:");
                zmsg_dump (msg);
            }
            //  We would handle malformed replies better in real code
            assert (zmsg_size (msg) >= 3);

            zframe_t *header = zmsg_pop (msg);
            assert (zframe_streq (header, MDPC_CLIENT));
            zframe_destroy (&header);

            zframe_t *reply_service = zmsg_pop (msg);
            assert (zframe_streq (reply_service, service));
            zframe_destroy (&reply_service);

            zmsg_destroy (&request);
            return msg;     //  Success
        }
        else
        if (--retries_left) {
            if (self->verbose)
                zclock_log ("W: no reply, reconnecting...");
            s_mdp_client_connect_to_broker (self);
        }
        else {
            if (self->verbose)
                zclock_log ("W: permanent error, abandoning");
            break;          //  Give up
        }
    }
    if (zctx_interrupted)
        printf ("W: interrupt received, killing client...\n");
    zmsg_destroy (&request);
    return NULL;
}
Beispiel #7
0
void watch_port(void *cvoid, 
                zctx_t * context, 
                void * pipe ) {
  zclock_log("watch_port started!");
  monitorconfig_t * config = (monitorconfig_t*) cvoid;
  dump_monitorconfig(config);

  void * linein = zsocket_new(context, ZMQ_SUB);
  char * listen_socket = to_linesocket(config->line_id);
  char line_id[16];
  sprintf(line_id, "%d", config->line_id);
  zsocket_connect(linein, listen_socket);
  zsockopt_set_unsubscribe(linein, "");
  zsockopt_set_subscribe(linein, "CLEAR_MONITORS");
  zsockopt_set_subscribe(linein, "VALUE");
  // have set up subscription, can signal parent that we're ok.
  child_handshake(pipe);
  zsocket_destroy(context, pipe); // no longer require pipe

  void * lineout = zsocket_new(context, ZMQ_PUB);
  zsocket_connect(lineout, config->out_socket);
  time_t until = time(NULL) + 60;
  while(time(NULL)<until) {
    zmsg_t * msg = zmsg_recv(linein);
    if(!msg) {
      zclock_log("monitor quitting!");
      return;
    }
    zframe_t * cmd = zmsg_pop(msg);
    if(zframe_streq(cmd, "CLEAR_MONITORS")) {
      zclock_log("ephemeral monitor quitting");
      zmsg_destroy(&msg);
      zframe_destroy(&cmd);
      break;
    } else if (zframe_streq(cmd, "VALUE")) {
      // TODO perhaps some rate limiting necessary
      assert(zmsg_size(msg) == 2);
      
      zframe_t * value = zmsg_pop(msg);
      int res = *(int*)zframe_data(value);
      char * new_channel = zmsg_popstr(msg);

      if(strcmp(new_channel, config->channel)!=0) {
        zclock_log("monitor on %d: listening for %s, channel changed to %s quitting",
                   config->line_id, config->channel, new_channel);
        zmsg_destroy(&msg);
        zframe_destroy(&cmd);
        break;
      }

      zmsg_t * to_send = zmsg_new();

      char buf[1024];
      sprintf(buf, "%d", res);
      zmsg_pushstr(to_send, buf);
      zmsg_pushstr(to_send, line_id);
      zmsg_pushstr(to_send, config->source_worker);
      zclock_log("%s sending line %s -> %s", config->source_worker, line_id, buf);
      zmsg_send(&to_send, lineout);
      // don't destroy value frame, now owned by zmsg
    }
    // else ignore
    zmsg_destroy(&msg);
    zframe_destroy(&cmd);
  }
  zclock_log("monitor on %d: listening for %s, expiring naturally",
             config->line_id, config->channel);
  //cleanup
  zsocket_destroy(context, linein);
  zsocket_destroy(context, lineout);

}