コード例 #1
0
ファイル: ppqueue.c プロジェクト: Carl4/zguide
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;
}
コード例 #2
0
ファイル: ppqueue.c プロジェクト: rryqszq4/sweet-clib
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://127.0.0.1:5555");
	zsocket_bind(backend, "tcp://127.0.0.1:5556");

	zlist_t *workers = zlist_new();

	uint64_t heartbeat_at = zclock_time() + HEARTBEAT_INTERVAL;

	while (true){
		zmq_pollitem_t items [] ={
			{backend, 0, ZMQ_POLLIN, 0},
			{frontend, 0, ZMQ_POLLIN, 0}
		};

		int rc = zmq_poll(items, zlist_size(worker)?2:1);
		if (rc == -1)
			break;

		if (items[0].revents & ZMQ_POLLIN){
			zmsg_t *msg = zmsg_recv(backend);
			if (!msg)
				break;

			zframe_t *identity = zmsg_unwrap(msg);
			worker_t *worker = s_worker_new(identity);
			s_worker_ready(worker, workers);

			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){
			zmsg_t *msg = zmsg_recv(frontend);
			if (!msg)
				break;
			zframe_t *identity = s_workers_next(workers);
			zmsg_prepend(msg, &identity);
			zmsg_send(&msg, backend);
		}

		if (zclock_time() >= heartbeat_at){
			worker_t *worker = (worker_t *)zlist_first(workers);
			while (worker){
				zframe_send(&worker->identity, 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);
	}

	while (zlist_size(workers)){
		worker_t *worker = (worker_t *)zlist_pop(workers);
		s_worker_destroy(&worker);
	}
	zlist_destroy(&workers);
	zctx_destroy(&ctx);
	return 0;
}