Using a Reactor

Up until now, we have used a poll loop in the server. In this next model of the server, we switch to using a reactor. In C, we use CZMQ’s zloop class. Using a reactor makes the code more verbose but easier to understand and build out, because each piece of the server is handled by a separate reactor handler.

We use a single thread and pass a server object around to the reactor handlers. We could have organized the server as multiple threads, each handling one socket or timer, but that works better when threads don’t have to share data. In this case, all work is centered around the server’s hashmap, so one thread is simpler.

There are three reactor handlers:

  • One to handle snapshot requests coming on the ROUTER socket

  • One to handle incoming updates from clients, coming on the PULL socket

  • One to expire ephemeral values that have passed their TTL

The code for Model Five of the Clone server is shown in Example 5-46.

Example 5-46. Clone server, Model Five (clonesrv5.c)

//
//  Clone server — Model Five
//

//  Lets us build this source without creating a library
#include "kvmsg.c"

//  zloop reactor handlers
static int s_snapshots  (zloop_t *loop, zmq_pollitem_t *poller, void *args);
static int s_collector  (zloop_t *loop, zmq_pollitem_t *poller, void *args);
static int s_flush_ttl  (zloop_t *loop, zmq_pollitem_t *poller, void *args);

//  Our server is defined by these properties
typedef struct {
    zctx_t *ctx;                //  Context wrapper
    zhash_t *kvmap;             //  Key-value store
    zloop_t *loop ...

Get ZeroMQ now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.