Beispiel #1
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);
}
Beispiel #2
0
int main (int argc, char *argv [])
{
    if (argc == 1) {
        printf ("I: syntax: %s <endpoint> ...\n", argv [0]);
        exit (EXIT_SUCCESS);
    }
    //  Create new freelance client object
    flclient_t *client = flclient_new ();
    
    //  Connect to each endpoint
    int argn;
    for (argn = 1; argn < argc; argn++)
        flclient_connect (client, argv [argn]);
    
    //  Send a bunch of name resolution 'requests', measure time
    int requests = 10000;
    uint64_t start = s_clock ();
    while (requests--) {
        zmsg_t *request = zmsg_new ("random name");
        zmsg_t *reply = flclient_request (client, &request);
        if (!reply) {
            printf ("E: name service not available, aborting\n");
            exit (EXIT_FAILURE);
        }
        zmsg_destroy (&reply);
    }
    printf ("Average round trip cost: %d usec\n", 
        (int) (s_clock () - start) / 10);
    
    flclient_destroy (&client);
    return 0;
}
Beispiel #3
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);
}
Beispiel #4
0
int main(){

    void* context = zmq_init(1);
    void* receiver = zmq_socket(context, ZMQ_PULL);

    zmq_bind(receiver, "tcp://*:5558");

    //wait for start of batch
    char *string = s_recv(receiver);
    free(string);

    //start clock
    int64_t start_time = s_clock();

    //process 100
    int tasks_nbr;
    for( tasks_nbr = 0; tasks_nbr < 100; tasks_nbr++){
        char* string = s_recv(receiver);
        if((tasks_nbr / 10)*10 == tasks_nbr){
            printf(":");
        } else{
            printf(".");
        }
        fflush(stdout);
    }

    printf("Total elapsed time: %d msec\n", 
            (int)(s_clock() - start_time));

    zmq_close(receiver);
    zmq_term(context);
    return 0;
}
Beispiel #5
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;
}
Beispiel #6
0
int main (int argc, char *argv [])
{
    int verbose = (argc > 1 && streq (argv [1], "-v"));

    s_version_assert (2, 1);
    s_catch_signals ();
    broker_t *self = s_broker_new (verbose);
    s_broker_bind (self, "tcp://*:5555");

    //  Get and process messages forever or until interrupted
    while (!s_interrupted) {
        zmq_pollitem_t items [] = { 
            { self->socket,  0, ZMQ_POLLIN, 0 } };
        zmq_poll (items, 1, HEARTBEAT_INTERVAL * 1000);

        //  Process next input message, if any
        if (items [0].revents & ZMQ_POLLIN) {
            zmsg_t *msg = zmsg_recv (self->socket);
            if (self->verbose) {
                s_console ("I: received message:");
                zmsg_dump (msg);
            }
            char *sender = zmsg_pop (msg);
            char *empty  = zmsg_pop (msg);
            char *header = zmsg_pop (msg);

            if (streq (header, MDPC_CLIENT))
                s_client_process (self, sender, msg);
            else
            if (streq (header, MDPW_WORKER))
                s_worker_process (self, sender, msg);
            else {
                s_console ("E: invalid message:");
                zmsg_dump (msg);
                zmsg_destroy (&msg);
            }
            free (sender);
            free (empty);
            free (header);
        }
        //  Disconnect and delete any expired workers
        //  Send heartbeats to idle workers if needed
        if (s_clock () > self->heartbeat_at) {
            s_broker_purge_workers (self);
            worker_t *worker = zlist_first (self->waiting);
            while (worker) {
                s_worker_send (self, worker, MDPW_HEARTBEAT, NULL, NULL);
                worker = zlist_next (self->waiting);
            }
            self->heartbeat_at = s_clock () + HEARTBEAT_INTERVAL;
        }
    }
    if (s_interrupted)
        printf ("W: interrupt received, shutting down...\n");

    s_broker_destroy (&self);
    return 0;
}
Beispiel #7
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;
}
Beispiel #8
0
server_t *
server_new (char *endpoint)
{
    server_t *self = (server_t *) malloc (sizeof (server_t));
    self->endpoint = strdup (endpoint);
    self->alive = 0;
    self->ping_at = s_clock () + PING_INTERVAL;
    self->expires = s_clock () + SERVER_TTL;
    return self;
}
Beispiel #9
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;
}
int main(void)
{
    //Create ZMQ Socket
    void *context = zmq_ctx_new();
    
    //Socket to receive messages
    void *receiver = zmq_socket(context, ZMQ_PULL);
    zmq_bind(receiver, "tcp://*:5558");
    
    //Socket to control workers
    void *controller = zmq_socket(context, ZMQ_PUB);
    zmq_bind(controller, "tcp://*:5559");
    
    //Waiting for start 
    char *string = s_recv(receiver);
    free(string);
    
    //Start clock
    int64_t start_time = s_clock();
    
    //Process messages
    int task_nbr;
    for(task_nbr = 0; task_nbr < 100; task_nbr++)
    {
        char *string = s_recv(receiver);
        free(string);
        if((task_nbr / 10) * 10 == task_nbr)
        {
            printf(":");
        }
        else
        {
            printf(".");
        }
        fflush(stdout);
    }
    
    printf("Total elapsed time: %d msec\n", (int)(s_clock()-start_time));
    
    //Send Kille signal
    s_send(controller, "KILL");
    
    zmq_close(receiver);
    zmq_close(controller);
    zmq_ctx_destroy(context);
    
    return 0;
}
Beispiel #11
0
 broker (int verbose)
 {
     //  Initialize broker state
     m_context = new zmq::context_t(1);
     m_socket = new zmq::socket_t(*m_context, ZMQ_ROUTER);
     m_verbose = verbose;
     m_heartbeat_at = s_clock () + HEARTBEAT_INTERVAL;
 }
Beispiel #12
0
   //  Get and process messages forever or until interrupted
   void
   start_brokering() {
      while (!s_interrupted) {
          zmq::pollitem_t items [] = {
              { *m_socket,  0, ZMQ_POLLIN, 0 } };
          zmq::poll (items, 1, HEARTBEAT_INTERVAL);

          //  Process next input message, if any
          if (items [0].revents & ZMQ_POLLIN) {
              zmsg *msg = new zmsg(*m_socket);
              if (m_verbose) {
                  s_console ("I: received message:");
                  msg->dump ();
              }
              std::string sender = std::string((char*)msg->pop_front ().c_str());
              msg->pop_front (); //empty message
              std::string header = std::string((char*)msg->pop_front ().c_str());

//              std::cout << "sbrok, sender: "<< sender << std::endl;
//              std::cout << "sbrok, header: "<< header << std::endl;
//              std::cout << "msg size: " << msg->parts() << std::endl;
//              msg->dump();
              if (header.compare(MDPC_CLIENT) == 0) {
                  client_process (sender, msg);
              }
              else if (header.compare(MDPW_WORKER) == 0) {
                  worker_process (sender, msg);
              }
              else {
                  s_console ("E: invalid message:");
                  msg->dump ();
                  delete msg;
              }
          }
          //  Disconnect and delete any expired workers
          //  Send heartbeats to idle workers if needed
          if (s_clock () > m_heartbeat_at) {
              purge_workers ();
              for (std::vector<worker*>::iterator it = m_waiting.begin();
                    it != m_waiting.end() && (*it)!=0; it++) {
                  worker_send (*it, (char*)MDPW_HEARTBEAT, "", NULL);
              }
              m_heartbeat_at = s_clock () + HEARTBEAT_INTERVAL;
          }
      }
   }
Beispiel #13
0
   void
   worker_process (std::string sender, zmsg *msg)
   {
       assert (msg && msg->parts() >= 1);     //  At least, command

       std::string command = (char *)msg->pop_front().c_str();
       bool worker_ready = m_workers.count(sender)>0;
       worker *wrk = worker_require (sender);

       if (command.compare (MDPW_READY) == 0) {
           if (worker_ready)  {              //  Not first command in session
               worker_delete (wrk, 1);
           }
           else {
               if (sender.size() >= 4  //  Reserved service name
               &&  sender.find_first_of("mmi.") == 0) {
                   worker_delete (wrk, 1);
               } else {
                   //  Attach worker to service and mark as idle
                   std::string service_name = (char*)msg->pop_front ().c_str();
                   wrk->m_service = service_require (service_name);
                   wrk->m_service->m_workers++;
                   worker_waiting (wrk);
               }
           }
       } else {
          if (command.compare (MDPW_REPLY) == 0) {
              if (worker_ready) {
                  //  Remove & save client return envelope and insert the
                  //  protocol header and service name, then rewrap envelope.
                  std::string client = msg->unwrap ();
                  msg->wrap (MDPC_CLIENT, wrk->m_service->m_name.c_str());
                  msg->wrap (client.c_str(), "");
                  msg->send (*m_socket);
                  worker_waiting (wrk);
              }
              else {
                  worker_delete (wrk, 1);
              }
          } else {
             if (command.compare (MDPW_HEARTBEAT) == 0) {
                 if (worker_ready) {
                     wrk->m_expiry = s_clock () + HEARTBEAT_EXPIRY;
                 } else {
                     worker_delete (wrk, 1);
                 }
             } else {
                if (command.compare (MDPW_DISCONNECT) == 0) {
                    worker_delete (wrk, 0);
                } else {
                    s_console ("E: invalid input message (%d)", (int) *command.c_str());
                    msg->dump ();
                }
             }
          }
       }
       delete msg;
   }
Beispiel #14
0
static void
s_worker_process (broker_t *self, char *sender, zmsg_t *msg)
{
    assert (zmsg_parts (msg) >= 1);     //  At least, command

    char *command = zmsg_pop (msg);
    int worker_ready = (zhash_lookup (self->workers, sender) != NULL);
    worker_t *worker = s_worker_require (self, sender);

    if (streq (command, MDPW_READY)) {
        if (worker_ready)               //  Not first command in session
            s_worker_delete (self, worker, 1);
        else
        if (strlen (sender) >= 4  //  Reserved service name
        &&  memcmp (sender, "mmi.", 4) == 0)
            s_worker_delete (self, worker, 1);
        else {
            //  Attach worker to service and mark as idle
            char *service_name = zmsg_pop (msg);
            worker->service = s_service_require (self, service_name);
            worker->service->workers++;
            s_worker_waiting (self, worker);
            free (service_name);
        }
    }
    else
    if (streq (command, MDPW_REPLY)) {
        if (worker_ready) {
            //  Remove & save client return envelope and insert the
            //  protocol header and service name, then rewrap envelope.
            char *client = zmsg_unwrap (msg);
            zmsg_wrap (msg, MDPC_CLIENT, worker->service->name);
            zmsg_wrap (msg, client, "");
            free (client);
            zmsg_send (&msg, self->socket);
            s_worker_waiting (self, worker);
        }
        else
            s_worker_delete (self, worker, 1);
    }
    else
    if (streq (command, MDPW_HEARTBEAT)) {
        if (worker_ready)
            worker->expiry = s_clock () + HEARTBEAT_EXPIRY;
        else
            s_worker_delete (self, worker, 1);
    }
    else
    if (streq (command, MDPW_DISCONNECT))
        s_worker_delete (self, worker, 0);
    else {
        s_console ("E: invalid input message (%d)", (int) *command);
        zmsg_dump (msg);
    }
    free (command);
    zmsg_destroy (&msg);
}
Beispiel #15
0
static void
s_worker_waiting (broker_t *self, worker_t *worker)
{
    //  Queue to broker and service waiting lists
    zlist_append (self->waiting, worker);
    zlist_append (worker->service->waiting, worker);
    worker->expiry = s_clock () + HEARTBEAT_EXPIRY;
    s_service_dispatch (self, worker->service, NULL);
}
Beispiel #16
0
//  .split main task
//  While this example runs in a single process, that is just to make
//  it easier to start and stop the example. Each thread has its own
//  context and conceptually acts as a separate process.
int main() {
    zmq::context_t context(1);
    zmq::socket_t broker(context, ZMQ_ROUTER);

    broker.bind("tcp://*:5671");
    srandom((unsigned)time(NULL));

    const int NBR_WORKERS = 10;
    pthread_t workers[NBR_WORKERS];
    for (int worker_nbr = 0; worker_nbr < NBR_WORKERS; ++worker_nbr) {
        pthread_create(workers + worker_nbr, NULL, worker_task, (void *)(intptr_t)worker_nbr);
    }


    //  Run for five seconds and then tell workers to end
    int64_t end_time = s_clock() + 5000;
    int workers_fired = 0;
    while (1) {
        //  Next message gives us least recently used worker
        std::string identity = s_recv(broker);
        {
            s_recv(broker);     //  Envelope delimiter
            s_recv(broker);     //  Response from worker
        }

        s_sendmore(broker, identity);
        s_sendmore(broker, "");

        //  Encourage workers until it's time to fire them
        if (s_clock() < end_time)
            s_send(broker, "Work harder");
        else {
            s_send(broker, "Fired!");
            if (++workers_fired == NBR_WORKERS)
                break;
        }
    }

    for (int worker_nbr = 0; worker_nbr < NBR_WORKERS; ++worker_nbr) {
        pthread_join(workers[worker_nbr], NULL);
    }

    return 0;
}
//  Look for & kill expired workers
static void
s_queue_purge (std::vector<worker_t> &queue)
{
    int64_t clock = s_clock();
    for (std::vector<worker_t>::iterator it = queue.begin(); it < queue.end(); it++) {
        if (clock > it->expiry) {
           it = queue.erase(it)-1;
        }
    }
}
Beispiel #18
0
 void
 worker_waiting (worker *worker)
 {
     assert (worker);
     //  Queue to broker and service waiting lists
     m_waiting.push_back(worker);
     worker->m_service->m_waiting.push_back(worker);
     worker->m_expiry = s_clock () + HEARTBEAT_EXPIRY;
     // Attempt to process outstanding requests
     service_dispatch (worker->m_service, 0);
 }
Beispiel #19
0
int main (void) 
{
    //  Socket to receive messages on
    void *context = zmq_ctx_new ();
    void *receiver = zmq_socket (context, ZMQ_PULL);
    zmq_bind (receiver, "tcp://*:5558");

    //  Socket for worker control
    void *controller = zmq_socket (context, ZMQ_PUB);
    zmq_bind (controller, "tcp://*:5559");

    //  Wait for start of batch
    char *string = s_recv (receiver);
    free (string);
    
    //  Start our clock now
    int64_t start_time = s_clock ();

    //  Process 100 confirmations
    int task_nbr;
    for (task_nbr = 0; task_nbr < 100; task_nbr++) {
        char *string = s_recv (receiver);
        free (string);
        if (task_nbr % 10 == 0)
            printf (":");
        else
            printf (".");
        fflush (stdout);
    }
    printf ("Total elapsed time: %d msec\n", 
        (int) (s_clock () - start_time));

    //  Send kill signal to workers
    s_send (controller, "KILL");

    zmq_close (receiver);
    zmq_close (controller);
    zmq_ctx_destroy (context);
    return 0;
}
Beispiel #20
0
int main(void)
{
    // Prepare our context and socket
    void *context = zmq_ctx_new();
    void *receiver = zmq_socket(context, ZMQ_PULL);
    zmq_bind(receiver, "tcp://*:5558");

    // Wait for start of batch
    char *string = s_recv(receiver);
    free(string);
    printf("start of batch\n");

    // Start our clock now
    int64_t start_time = s_clock();

    // Process 100 confirmations
    int task_nbr;
    for(task_nbr=0; task_nbr<100; task_nbr++)
    {
        char *string = s_recv(receiver);
        free(string);
        if(task_nbr % 10 == 0)
        {
            printf(":");
        }
        else
        {
            printf(".");
        }
        fflush(stdout);
    }

    // Calculate and report duration of batch
    printf("\nTotal elapsed time: %d msec\n", (int)(s_clock() - start_time));
    
    zmq_close(receiver);
    zmq_ctx_destroy(context);
    return 0;
}
Beispiel #21
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;
}
Beispiel #22
0
static broker_t *
s_broker_new (int verbose)
{
    broker_t *self = (broker_t *) calloc (1, sizeof (broker_t));

    //  Initialize broker state
    self->context = zmq_init (1);
    self->socket = zmq_socket (self->context, ZMQ_XREP);
    self->verbose = verbose;
    self->services = zhash_new ();
    self->workers = zhash_new ();
    self->waiting = zlist_new ();
    self->heartbeat_at = s_clock () + HEARTBEAT_INTERVAL;
    return self;
}
//  Reset worker expiry, worker must be present
static void
s_worker_refresh (std::vector<worker_t> &queue, std::string &identity)
{
    bool found = false;
    for (std::vector<worker_t>::iterator it = queue.begin(); it < queue.end(); it++) {
        if (it->identity.compare(identity) == 0) {
           it->expiry = s_clock ()
                 + HEARTBEAT_INTERVAL * HEARTBEAT_LIVENESS;
           found = true;
           break;
        }
    }
    if (!found) {
       std::cout << "E: worker " << identity << " not ready" << std::endl;
    }
}
//  Insert worker at end of queue, reset expiry
//  Worker must not already be in queue
static void
s_worker_append (std::vector<worker_t> &queue, std::string &identity)
{
    bool found = false;
    for (std::vector<worker_t>::iterator it = queue.begin(); it < queue.end(); it++) {
        if (it->identity.compare(identity) == 0) {
            std::cout << "E: duplicate worker identity " << identity.c_str() << std::endl;
            found = true;
            break;
        }
    }
    if (!found) {
        worker_t worker;
        worker.identity = identity;
        worker.expiry = s_clock() + HEARTBEAT_INTERVAL * HEARTBEAT_LIVENESS;
        queue.push_back(worker);
    }
}
Beispiel #25
0
int main2 (int argc, char *argv[])
{
    //  Prepare our context and socket
    zmq::context_t context(1);
    zmq::socket_t receiver(context,ZMQ_PULL);
	receiver.bind("tcp://*:5558");

    //  Wait for start of batch
    zmq::message_t message;
    receiver.recv(&message);

    //  Start our clock now
    //struct timeval tstart;
    //gettimeofday (&tstart, NULL);
	int64_t tstart = s_clock();

    //  Process 100 confirmations
    int task_nbr;
    int total_msec = 0;     //  Total calculated cost in msecs
    for (task_nbr = 0; task_nbr < 100; task_nbr++) {

        receiver.recv(&message);
        if ((task_nbr / 10) * 10 == task_nbr)
            std::cout << ":" << std::flush;
        else
            std::cout << "." << std::flush;
    }
    //  Calculate and report duration of batch
    //struct timeval tend, tdiff;
    //gettimeofday (&tend, NULL);
	//int64_t tend = s_clock();

    //if (tend.tv_usec < tstart.tv_usec) {
    //    tdiff.tv_sec = tend.tv_sec - tstart.tv_sec - 1;
    //    tdiff.tv_usec = 1000000 + tend.tv_usec - tstart.tv_usec;
    //}
    //else {
    //    tdiff.tv_sec = tend.tv_sec - tstart.tv_sec;
    //    tdiff.tv_usec = tend.tv_usec - tstart.tv_usec;
    //}
    //total_msec = tend - tstart;//stdiff.tv_sec * 1000 + tdiff.tv_usec / 1000;
    std::cout << "\nTotal elapsed time: " << total_msec << " msec\n" << std::endl;
    return 0;
}
Beispiel #26
0
    void connect_to_broker ()
    {
        if (m_worker) {
            delete m_worker;
        }
        m_worker = new zmq::socket_t (*m_context, ZMQ_DEALER);
        int linger = 0;
        m_worker->setsockopt (ZMQ_LINGER, &linger, sizeof (linger));
        m_worker->connect (m_broker.c_str());
        if (m_verbose)
            s_console ("I: connecting to broker at %s...", m_broker.c_str());

        //  Register service with broker
        send_to_broker ((char*)MDPW_READY, m_service, NULL);

        //  If liveness hits zero, queue is considered disconnected
        m_liveness = HEARTBEAT_LIVENESS;
        m_heartbeat_at = s_clock () + m_heartbeat;
    }
Beispiel #27
0
 void
 purge_workers ()
 {
     int64_t now = s_clock();
     for (size_t i = 0; i < m_waiting.size();)
     {
         worker* wrk = m_waiting[i];
         if (wrk->m_expiry > now)
         {
             ++i;
             continue;
         }
         if (m_verbose) {
             s_console ("I: deleting expired worker: %s",
                   wrk->m_identity.c_str());
         }
         worker_delete (wrk, 0);
     }
 }
Beispiel #28
0
void s_connect_to_broker (mdwrk_t *self)
{
    if (self->worker)
        zmq_close (self->worker);
    self->worker = zmq_socket (self->context, ZMQ_XREQ);
    int linger = 0;
    zmq_setsockopt (self->worker, ZMQ_LINGER, &linger, sizeof (linger));
    zmq_connect (self->worker, self->broker);

    //  Register service with broker
    zmsg_t *msg = zmsg_new ();
    zmsg_append (msg, MDPS_HEADER);
    zmsg_append (msg, MDPS_READY);
    zmsg_append (msg, self->service);
    zmsg_send (&msg, self->worker);

    //  If liveness hits zero, queue is considered disconnected
    self->liveness = HEARTBEAT_LIVENESS;
    self->heartbeat_at = s_clock () + HEARTBEAT_INTERVAL;
}
int main(int argc, char *argv[])
{
    char ch;
    char str[STR_BUFFSIZE];

    char plom_help_string[] =
        "PLOM Kalman\n"
        "usage:\n"
        "kalman [implementation] [--no_dem_sto] [--no_white_noise] [--no_diff]\n"
        "                        [-s, --DT <float>] [--eps_abs <float>] [--eps_rel <float>]\n"
        "                        [-g, --freeze_forcing <float>]\n"
        "                        [-r, --traj] [-p, --path <path>] [-i, --id <integer>]\n"
        "                        [-b, --no_trace] [-e, --no_hat] [--prior] [--transf]\n"
	"                        [-q, --quiet] [-P, --pipe]"
        "                        [-h, --help]\n"
        "where implementation is 'sde' (default)\n"
        "options:\n"
	"\n"
        "-q, --quiet        no verbosity\n"
        "-P, --pipe         pipe mode (echo theta.json on stdout)\n"
	"\n"
        "--no_dem_sto       turn off demographic stochasticity (if possible)\n"
        "--no_white_noise       turn off environmental stochasticity (if any)\n"
        "--no_diff         turn off drift (if any)\n"
	"\n"
        "-s, --DT           Initial integration time step\n"
	"--eps_abs          Absolute error for adaptive step-size contro\n"
	"--eps_rel          Relative error for adaptive step-size contro\n"
        "-g, --freeze_forcing  freeze the metadata to their value at the specified time\n"
	"\n"
        "-r, --traj         print the trajectories\n"
        "--prior            add log(prior) to the estimated loglik\n"
        "--transf           add log(JacobianDeterminant(transf)) to the estimated loglik. (combined to --prior, gives posterior density in transformed space)\n"
        "-p, --path         path where the outputs will be stored\n"
        "-b, --no_trace     do not write trace_<id>.output file\n"
        "-h, --no_hat       do not write hat_<general_id>.output file\n"
        "-d, --no_pred_res  do not write pred_res_<general_id>.output file (prediction residuals)\n"
        "-i, --id           general id (unique integer identifier that will be appended to the output files)\n"
        "-l, --LIKE_MIN     particles with likelihood smaller that LIKE_MIN are considered lost\n"
	"-o, --nb_obs       number of observations to be fitted (for tempering)"
        "-h, --help         print the usage on stdout\n";


    // general options
    GENERAL_ID =0;
    snprintf(SFR_PATH, STR_BUFFSIZE, "%s", DEFAULT_PATH);
    LIKE_MIN = 1e-17;
    LOG_LIKE_MIN = log(LIKE_MIN);
    enum plom_print print_opt = PLOM_PRINT_BEST | PLOM_PRINT_HAT | PLOM_PRINT_PRED_RES;

    // options
    OPTION_PRIOR = 0;
    OPTION_TRANSF = 0;
    int nb_obs = -1;
    double freeze_forcing = -1.0;

    double dt = 0.0, eps_abs = PLOM_EPS_ABS, eps_rel = PLOM_EPS_REL;

    J = 1; //not an option, needed for print_X



    enum plom_implementations implementation;
    enum plom_noises_off noises_off = 0;


    static struct option long_options[] = {
	{"traj",       no_argument,       0, 'r'},
	{"no_dem_sto", no_argument,       0, 'x'},
	{"no_white_noise", no_argument,       0, 'y'},
	{"no_diff",   no_argument,       0, 'z'},

	{"DT",         required_argument, 0, 's'},
	{"eps_abs",    required_argument, 0, 'v'},
	{"eps_rel",    required_argument, 0, 'w'},
	{"freeze_forcing", required_argument, 0, 'g'},
        {"help",       no_argument,       0, 'h'},
        {"path",       required_argument, 0, 'p'},
        {"id",         required_argument, 0, 'i'},
	{"no_trace",   no_argument,       0, 'b'},
	{"no_hat",     no_argument,       0, 'e'},
	{"no_pred_res",no_argument,       0, 'd'},

        {"prior", no_argument, &OPTION_PRIOR, 1},
        {"transf", no_argument, &OPTION_TRANSF, 1},
	{"nb_obs", required_argument,  0, 'o'},

	{"quiet",  no_argument,       0, 'q'},
	{"pipe",  no_argument,       0, 'P'},

        {"LIKE_MIN",   required_argument, 0, 'l'},

        {0, 0, 0, 0}
    };

    int option_index = 0;
    while ((ch = getopt_long (argc, argv, "qPxyzs:v:w:i:l:p:rbhedo:g:", long_options, &option_index)) != -1) {
        switch (ch) {
        case 0:
            break;

        case 'x':
            noises_off = noises_off | PLOM_NO_DEM_STO;
            break;
        case 'y':
            noises_off = noises_off | PLOM_NO_ENV_STO;
            break;
        case 'z':
            noises_off = noises_off | PLOM_NO_DRIFT;
            break;
	case 'o':
	    nb_obs = atoi(optarg);
            break;

        case 'g':
            freeze_forcing = atof(optarg);
            break;

        case 's':
            dt = atof(optarg);
            break;
        case 'v':
            eps_abs = atof(optarg);
            break;
        case 'w':
            eps_rel = atof(optarg);
            break;

        case 'h':
            print_log(plom_help_string);
            return 1;

        case 'p':
            snprintf(SFR_PATH, STR_BUFFSIZE, "%s", optarg);
            break;
        case 'i':
            GENERAL_ID = atoi(optarg);
            break;
        case 'l':
            LIKE_MIN = atof(optarg);
            LOG_LIKE_MIN = log(LIKE_MIN);
            break;
        case 'r':
	    print_opt |= PLOM_PRINT_X;
            break;
        case 'b':
	    print_opt &= ~PLOM_PRINT_BEST;
            break;
        case 'e':
	    print_opt &= ~PLOM_PRINT_HAT;
            break;
        case 'd':
	    print_opt &= ~PLOM_PRINT_PRED_RES;
            break;

        case 'q':
	    print_opt |= PLOM_QUIET;
            break;
        case 'P':
	    print_opt |= PLOM_PIPE | PLOM_QUIET;
            break;


        case '?':
            /* getopt_long already printed an error message. */
            return 1;

        default:
            snprintf(str, STR_BUFFSIZE, "Unknown option '-%c'\n", optopt);
            print_err(str);
            return 1;
        }
    }
    argc -= optind;
    argv += optind;


    if(argc == 0) {
	implementation = PLOM_ODE; //with Kalman the SDE uses f_pred of PLOM_ODE (OK will do better)...
    } else {
        if (!strcmp(argv[0], "sde")) {
            implementation = PLOM_ODE;
        } else {
            print_log(plom_help_string);
            return 1;
        }
    }

    plom_unlink_done(SFR_PATH, GENERAL_ID);
    json_t *settings = load_settings(PATH_SETTINGS);

    if (!(print_opt & PLOM_QUIET)) {
	snprintf(str, STR_BUFFSIZE, "Starting plom-Kalman with the following options: i = %d, LIKE_MIN = %g", GENERAL_ID, LIKE_MIN);
	print_log(str);
    }

    json_t *theta = load_json();
    struct s_kalman *p_kalman = build_kalman(theta, settings, implementation, noises_off, OPTION_PRIOR, dt, eps_abs, eps_rel, freeze_forcing, nb_obs);
    json_decref(settings);

    int64_t time_begin, time_end;
    if (!(print_opt & PLOM_QUIET)) {
	time_begin = s_clock();
    }

    back_transform_theta2par(p_kalman->p_par, p_kalman->p_best->mean, p_kalman->p_data->p_it_all, p_kalman->p_data);
    linearize_and_repeat(p_kalman->p_X, p_kalman->p_par, p_kalman->p_data, p_kalman->p_data->p_it_par_sv);
    prop2Xpop_size(p_kalman->p_X, p_kalman->p_data, p_kalman->calc[0]);
    theta_driftIC2Xdrift(p_kalman->p_X, p_kalman->p_best->mean, p_kalman->p_data);

    FILE *p_file_X = (print_opt & PLOM_PRINT_X) ? plom_fopen(SFR_PATH, GENERAL_ID, "X", "w", header_X, p_kalman->p_data): NULL;
    FILE *p_file_hat = (print_opt & PLOM_PRINT_HAT) ? plom_fopen(SFR_PATH, GENERAL_ID, "hat", "w", header_hat, p_kalman->p_data): NULL;
    FILE *p_file_pred_res = (print_opt & PLOM_PRINT_PRED_RES) ? plom_fopen(SFR_PATH, GENERAL_ID, "pred_res", "w", header_prediction_residuals_ekf, p_kalman->p_data): NULL;

    double log_like = run_kalman(p_kalman->p_X, p_kalman->p_best, p_kalman->p_par, p_kalman->p_kalman_update, p_kalman->p_data, p_kalman->calc, f_prediction_ode, 0, p_file_X, p_file_hat, p_file_pred_res, print_opt);


    if (print_opt & PLOM_PRINT_X) {
        plom_fclose(p_file_X);
    }

    if (print_opt & PLOM_PRINT_HAT) {
        plom_fclose(p_file_hat);
    }

    if (print_opt & PLOM_PRINT_PRED_RES) {
        plom_fclose(p_file_pred_res);
    }

    if (!(print_opt & PLOM_QUIET)) {
	time_end = s_clock();
	struct s_duration t_exec = time_exec(time_begin, time_end);
	sprintf(str, "logV: %g", log_like);
	print_log(str);

	sprintf(str, "Done in:= %dd %dh %dm %gs", t_exec.d, t_exec.h, t_exec.m, t_exec.s);
	print_log(str);
    }

    if (print_opt & PLOM_PRINT_BEST) {
        FILE *p_file_trace = plom_fopen(SFR_PATH, GENERAL_ID, "trace", "w", header_trace, p_kalman->p_data);
        print_trace(p_file_trace, 0, p_kalman->p_best, p_kalman->p_data, log_like);
        plom_fclose(p_file_trace);
    }

    plom_print_done(theta, p_kalman->p_data, p_kalman->p_best, SFR_PATH, GENERAL_ID, print_opt);

    if (!(print_opt & PLOM_QUIET)) {
	print_log("clean up...");
    }

    json_decref(theta);
    clean_kalman(p_kalman);

    return 0;
}
Beispiel #30
0
int main (void)
{
    s_version_assert (2, 1);
    srandom ((unsigned) time (NULL));

    void *context = zmq_init (1);
    void *worker = s_worker_socket (context);

    //  If liveness hits zero, queue is considered disconnected
    size_t liveness = HEARTBEAT_LIVENESS;
    size_t interval = INTERVAL_INIT;

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

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

        if (items [0].revents & ZMQ_POLLIN) {
            //  Get message
            //  - 3-part envelope + content -> request
            //  - 1-part "HEARTBEAT" -> heartbeat
            zmsg_t *msg = zmsg_recv (worker);

            if (msg_parts (msg) == 3) {
                //  Simulate various problems, after a few cycles
                cycles++;
                if (cycles > 3 && randof (5) == 0) {
                    printf ("I: (%s) simulating a crash\n", identity);
                    zmsg_destroy (&msg);
                    break;
                }
                else
                if (cycles > 3 && randof (5) == 0) {
                    printf ("I: (%s) simulating CPU overload\n", identity);
                    sleep (5);
                }
                printf ("I: (%s) normal reply - %s\n",
                    identity, zmsg_body (msg));
                zmsg_send (&msg, worker);
                liveness = HEARTBEAT_LIVENESS;
                sleep (1);              //  Do some heavy work
            }
            else
            if (msg_parts (msg) == 1
            && strcmp (msg_body (msg), "HEARTBEAT") == 0)
                liveness = HEARTBEAT_LIVENESS;
            else {
                printf ("E: (%s) invalid message\n", identity);
                zmsg_dump (msg);
            }
            interval = INTERVAL_INIT;
        }
        else
        if (--liveness == 0) {
            printf ("W: (%s) heartbeat failure, can't reach queue\n",
                identity);
            printf ("W: (%s) reconnecting in %zd msec...\n",
                identity, interval);
            s_sleep (interval);

            if (interval < INTERVAL_MAX)
                interval *= 2;
            zmq_close (worker);
            worker = s_worker_socket (context);
            liveness = HEARTBEAT_LIVENESS;
        }

        //  Send heartbeat to queue if it's time
        if (s_clock () > heartbeat_at) {
            heartbeat_at = s_clock () + HEARTBEAT_INTERVAL;
            printf ("I: (%s) worker heartbeat\n", identity);
            s_send (worker, "HEARTBEAT");
        }
    }
    zmq_close (worker);
    zmq_term (context);
    return 0;
}