Ejemplo n.º 1
0
int main (void) 
{
    s_version_assert (2, 1);
    void *context = zmq_init (1);

    //  Socket to talk to clients
    void *publisher = zmq_socket (context, ZMQ_PUB);
    zmq_bind (publisher, "tcp://*:5561");

    //  Socket to receive signals
    void *syncservice = zmq_socket (context, ZMQ_REP);
    zmq_bind (syncservice, "tcp://*:5562");

    //  Get synchronization from subscribers
    int subscribers = 0;
    while (subscribers < SUBSCRIBERS_EXPECTED) {
        //  - wait for synchronization request
        char *string = s_recv (syncservice);
        free (string);
        //  - send synchronization reply
        s_send (syncservice, "");
        subscribers++;
    }
    //  Now broadcast exactly 1M updates followed by END
    int update_nbr;
    for (update_nbr = 0; update_nbr < 1000000; update_nbr++)
        s_send (publisher, "Rhubarb");

    s_send (publisher, "END");

    zmq_close (publisher);
    zmq_close (syncservice);
    zmq_term (context);
    return 0;
}
Ejemplo n.º 2
0
int main () {
    s_version_assert (2, 1);
    void *context = zmq_init (1);

    //  Socket to talk to clients
    void *clients = zmq_socket (context, ZMQ_XREP);
    zmq_bind (clients, "tcp://*:5555");

    //  Socket to talk to workers
    void *workers = zmq_socket (context, ZMQ_XREQ);
    zmq_bind (workers, "inproc://workers");

    //  Launch pool of worker threads
    int thread_nbr;
    for (thread_nbr = 0; thread_nbr != 5; thread_nbr++) {
        pthread_t worker;
        pthread_create (&worker, NULL, worker_routine, context);
    }
    //  Connect work threads to client threads via a queue
    zmq_device (ZMQ_QUEUE, clients, workers);

    //  We never get here but clean up anyhow
    zmq_close (clients);
    zmq_close (workers);
    zmq_term (context);
    return 0;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
int main (void)
{
    s_version_assert (2, 1);

    //  Prepare our context and sockets
    void *context = zmq_init (1);
    void *frontend = zmq_socket (context, ZMQ_XREP);
    void *backend  = zmq_socket (context, ZMQ_XREP);
    zmq_bind (frontend, "tcp://*:5555");    //  For clients
    zmq_bind (backend,  "tcp://*:5556");    //  For workers

    //  Queue of available workers
    int available_workers = 0;
    char *worker_queue [MAX_WORKERS];

    while (1) {
        zmq_pollitem_t items [] = {
            { backend,  0, ZMQ_POLLIN, 0 },
            { frontend, 0, ZMQ_POLLIN, 0 }
        };
        //  Poll frontend only if we have available workers
        if (available_workers)
            zmq_poll (items, 2, -1);
        else
            zmq_poll (items, 1, -1);

        //  Handle worker activity on backend
        if (items [0].revents & ZMQ_POLLIN) {
            zmsg_t *zmsg = zmsg_recv (backend);
            //  Use worker address for LRU routing
            assert (available_workers < MAX_WORKERS);
            worker_queue [available_workers++] = zmsg_unwrap (zmsg);

            //  Return reply to client if it's not a READY
            if (strcmp (zmsg_address (zmsg), "READY") == 0)
                zmsg_destroy (&zmsg);
            else
                zmsg_send (&zmsg, frontend);
        }
        if (items [1].revents & ZMQ_POLLIN) {
            //  Now get next client request, route to next worker
            zmsg_t *zmsg = zmsg_recv (frontend);
            //  REQ socket in worker needs an envelope delimiter
            zmsg_wrap (zmsg, worker_queue [0], "");
            zmsg_send (&zmsg, backend);

            //  Dequeue and drop the next worker address
            free (worker_queue [0]);
            DEQUEUE (worker_queue);
            available_workers--;
        }
    }
    //  We never exit the main loop
    return 0;
}
Ejemplo n.º 5
0
//  This main thread simply starts several clients, and a server, and then
//  waits for the server to finish.
//
int main () {
    s_version_assert (2, 1);

    pthread_t client_thread;
    pthread_create (&client_thread, NULL, client_task, NULL);
    pthread_create (&client_thread, NULL, client_task, NULL);
    pthread_create (&client_thread, NULL, client_task, NULL);

    pthread_t server_thread;
    pthread_create (&server_thread, NULL, server_task, NULL);
    pthread_join (server_thread, NULL);
    return 0;
}
Ejemplo n.º 6
0
   mdcli (std::string broker, int verbose)
   {
       assert (broker.size()!=0);
       s_version_assert (4, 0);

       m_broker = broker;
       m_context = new zmq::context_t(1);
       m_verbose = verbose;
       m_timeout = 2500;           //  msecs
       m_retries = 3;              //  Before we abandon
       m_client = 0;

       s_catch_signals ();
       connect_to_broker ();
   }
Ejemplo n.º 7
0
int main (int argc, char *argv [])
{
    int verbose = (argc > 1 && strcmp (argv [1], "-v") == 0);

    s_version_assert (4, 0);
    s_catch_signals ();
    broker brk(verbose);
    brk.bind ("tcp://*:5555");

    brk.start_brokering();

    if (s_interrupted)
        printf ("W: interrupt received, shutting down...\n");

    return 0;
}
Ejemplo n.º 8
0
    mdwrk (std::string broker, std::string service, int verbose)
    {
        s_version_assert (2, 1);

        m_broker = broker;
        m_service = service;
        m_context = new zmq::context_t (1);
        m_worker = 0;
        m_expect_reply = false;
        m_verbose = verbose;
        m_heartbeat = 2500;     //  msecs
        m_reconnect = 2500;     //  msecs

        s_catch_signals ();
        connect_to_broker ();
    }
Ejemplo n.º 9
0
mdcli_t *
mdcli_new (char *broker)
{
    mdcli_t
        *self;

    assert (broker);
    s_version_assert (2, 1);
    self = malloc (sizeof (mdcli_t));
    memset (self, 0, sizeof (mdcli_t));

    self->broker = strdup (broker);
    self->context = zmq_init (1);
    s_connect_to_broker (self);
    return (self);
}
Ejemplo n.º 10
0
mdcli_t *
mdcli_new (char *broker, int verbose)
{
    assert (broker);
    s_version_assert (2, 1);

    mdcli_t *self = (mdcli_t *) calloc (1, sizeof (mdcli_t));
    self->broker = strdup (broker);
    self->context = zmq_init (1);
    self->verbose = verbose;
    self->timeout = 2500;           //  msecs

    s_catch_signals ();
    s_mdcli_connect_to_broker (self);
    return self;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
0
int main (void)
{
    s_version_assert (2, 1);
    srand ((unsigned) time (NULL));

    zmq::context_t context (1);
    zmq::socket_t * 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
    int64_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 msg (*worker);

            if (msg.parts () == 3) {
                //  Simulate various problems, after a few cycles
                cycles++;
                if (cycles > 3 && within (5) == 0) {
                    std::cout << "I: (" << identity << ") simulating a crash" << std::endl;
                    msg.clear ();
                    break;
                }
                else {
                   if (cycles > 3 && within (5) == 0) {
                      std::cout << "I: (" << identity << ") simulating CPU overload" << std::endl;
                       s_sleep (5000);
                   }
                }
                std::cout << "I: (" << identity << ") normal reply - " << msg.body() << std::endl;
                msg.send (*worker);
                liveness = HEARTBEAT_LIVENESS;
                s_sleep (1000);              //  Do some heavy work
            }
            else {
               if (msg.parts () == 1
               && strcmp (msg.body (), "HEARTBEAT") == 0) {
                   liveness = HEARTBEAT_LIVENESS;
               }
               else {
                   std::cout << "E: (" << identity << ") invalid message" << std::endl;
                   msg.dump ();
               }
            }
            interval = INTERVAL_INIT;
        }
        else
        if (--liveness == 0) {
            std::cout << "W: (" << identity << ") heartbeat failure, can't reach queue" << std::endl;
            std::cout << "W: (" << identity << ") reconnecting in " << interval << " msec..." << std::endl;
            s_sleep (interval);

            if (interval < INTERVAL_MAX) {
                interval *= 2;
            }
            delete 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;
            std::cout << "I: (" << identity << ") worker heartbeat" << std::endl;
            s_send (*worker, "HEARTBEAT");
        }
    }
    delete worker;
    return 0;
}
int main (void)
{
    s_version_assert (4, 0);

    //  Prepare our context and sockets
    zmq::context_t context(1);
    zmq::socket_t frontend(context, ZMQ_ROUTER);
    zmq::socket_t backend (context, ZMQ_ROUTER);
    frontend.bind("tcp://*:5555");    //  For clients
    backend.bind ("tcp://*:5556");    //  For workers

    //  Queue of available workers
    std::vector<worker_t> queue;

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

    while (1) {
        zmq::pollitem_t items [] = {
            { static_cast<void *>(backend),  0, ZMQ_POLLIN, 0 },
            { static_cast<void *>(frontend), 0, ZMQ_POLLIN, 0 }
        };
        //  Poll frontend only if we have available workers
        if (queue.size()) {
            zmq::poll (items, 2, HEARTBEAT_INTERVAL);
        } else {
            zmq::poll (items, 1, HEARTBEAT_INTERVAL);
        }

        //  Handle worker activity on backend
        if (items [0].revents & ZMQ_POLLIN) {
            zmsg msg (backend);
            std::string identity(msg.unwrap ());

            //  Return reply to client if it's not a control message
            if (msg.parts () == 1) {
                if (strcmp (msg.address (), "READY") == 0) {
                    s_worker_delete (queue, identity);
                    s_worker_append (queue, identity);
                }
                else {
                   if (strcmp (msg.address (), "HEARTBEAT") == 0) {
                       s_worker_refresh (queue, identity);
                   } else {
                       std::cout << "E: invalid message from " << identity << std::endl;
                       msg.dump ();
                   }
                }
            }
            else {
                msg.send (frontend);
                s_worker_append (queue, identity);
            }
        }
        if (items [1].revents & ZMQ_POLLIN) {
            //  Now get next client request, route to next worker
            zmsg msg (frontend);
            std::string identity = std::string(s_worker_dequeue (queue));
            msg.push_front((char*)identity.c_str());
            msg.send (backend);
        }

        //  Send heartbeats to idle workers if it's time
        if (s_clock () > heartbeat_at) {
            for (std::vector<worker_t>::iterator it = queue.begin(); it < queue.end(); it++) {
                zmsg msg ("HEARTBEAT");
                msg.wrap (it->identity.c_str(), NULL);
                msg.send (backend);
            }
            heartbeat_at = s_clock () + HEARTBEAT_INTERVAL;
        }
        s_queue_purge(queue);
    }
    //  We never exit the main loop
    //  But pretend to do the right shutdown anyhow
    queue.clear();
    return 0;
}
Ejemplo n.º 14
0
int main (int argc, char *argv[])
{
    s_version_assert (2, 1);

    //  Prepare our context and sockets
    void *context = zmq_init (1);
    void *frontend = zmq_socket (context, ZMQ_XREP);
    void *backend  = zmq_socket (context, ZMQ_XREP);
    zmq_bind (frontend, "ipc://frontend.ipc");
    zmq_bind (backend,  "ipc://backend.ipc");

    int client_nbr;
    for (client_nbr = 0; client_nbr < NBR_CLIENTS; client_nbr++) {
        pthread_t client;
        pthread_create (&client, NULL, client_thread, NULL);
    }
    int worker_nbr;
    for (worker_nbr = 0; worker_nbr < NBR_WORKERS; worker_nbr++) {
        pthread_t worker;
        pthread_create (&worker, NULL, worker_thread, NULL);
    }
    //  Logic of LRU loop
    //  - Poll backend always, frontend only if 1+ worker ready
    //  - If worker replies, queue worker as ready and forward reply
    //    to client if necessary
    //  - If client requests, pop next worker and send request to it

    //  Queue of available workers
    int available_workers = 0;
    char *worker_queue [10];

    while (1) {
        //  Initialize poll set
        zmq_pollitem_t items [] = {
            //  Always poll for worker activity on backend
            { backend,  0, ZMQ_POLLIN, 0 },
            //  Poll front-end only if we have available workers
            { frontend, 0, ZMQ_POLLIN, 0 }
        };
        if (available_workers)
            zmq_poll (items, 2, -1);
        else
            zmq_poll (items, 1, -1);

        //  Handle worker activity on backend
        if (items [0].revents & ZMQ_POLLIN) {
            //  Queue worker address for LRU routing
            char *worker_addr = s_recv (backend);
            assert (available_workers < NBR_WORKERS);
            worker_queue [available_workers++] = worker_addr;

            //  Second frame is empty
            char *empty = s_recv (backend);
            assert (empty [0] == 0);
            free (empty);

            //  Third frame is READY or else a client reply address
            char *client_addr = s_recv (backend);

            //  If client reply, send rest back to frontend
            if (strcmp (client_addr, "READY") != 0) {
                empty = s_recv (backend);
                assert (empty [0] == 0);
                free (empty);
                char *reply = s_recv (backend);
                s_sendmore (frontend, client_addr);
                s_sendmore (frontend, "");
                s_send     (frontend, reply);
                free (reply);
                if (--client_nbr == 0)
                    break;      //  Exit after N messages
            }
            free (client_addr);
        }
        if (items [1].revents & ZMQ_POLLIN) {
            //  Now get next client request, route to LRU worker
            //  Client request is [address][empty][request]
            char *client_addr = s_recv (frontend);
            char *empty = s_recv (frontend);
            assert (empty [0] == 0);
            free (empty);
            char *request = s_recv (frontend);

            s_sendmore (backend, worker_queue [0]);
            s_sendmore (backend, "");
            s_sendmore (backend, client_addr);
            s_sendmore (backend, "");
            s_send     (backend, request);

            free (client_addr);
            free (request);

            //  Dequeue and drop the next worker address
            free (worker_queue [0]);
            DEQUEUE (worker_queue);
            available_workers--;
        }
    }
    zmq_close (frontend);
    zmq_close (backend);
    zmq_term (context);
    return 0;
}