Exemplo n.º 1
0
Arquivo: broker.c Projeto: tnako/DP
static void s_broker_worker_msg(broker_t *self, zframe_t *sender, zmsg_t *msg)
{
    assert (zmsg_size(msg) >= 1);     //  At least, command

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

    if (zframe_streq(command, MDPW_READY)) {
        if (worker_ready) {               //  Not first command in session
            s_worker_delete(worker, 1);
			// Додумать, по идеи синоним сердцебиения
		} else {
			if (zframe_size(sender) >= 4 &&  memcmp(zframe_data (sender), "mmi.", 4) == 0) {
				s_worker_delete(worker, 1);
				// Додумать, по идеи синоним сердцебиения
			} else {
				//  Attach worker to service and mark as idle
				zframe_t *service_frame = zmsg_pop(msg);
				worker->service = s_service_require(self, service_frame);
				worker->service->workers++;
				s_worker_waiting(worker);
				zframe_destroy(&service_frame);
			}
		}
    } else if (zframe_streq(command, MDPW_REPLY)) {
        if (worker_ready) {
            //  Remove and save client return envelope and insert the
            //  protocol header and service name, then rewrap envelope.
            zframe_t *client = zmsg_unwrap(msg);
            zmsg_pushstr(msg, worker->service->name);
            zmsg_pushstr(msg, MDPC_CLIENT);
            zmsg_wrap(msg, client);
            zmsg_send(&msg, self->socket);
            s_worker_waiting(worker);
        } else {
			// Просто обрыв связи между воркером и брокером
			// синоним сердцебиения
            s_worker_delete(worker, 1);
		}
    } else if (zframe_streq(command, MDPW_HEARTBEAT)) {
        if (worker_ready) {
            worker->expiry = zclock_time () + HEARTBEAT_EXPIRY;
		} else {
			// Просто обрыв связи между воркером и брокером
			// синоним сердцебиения
            s_worker_delete(worker, 1);
		}
    } else if (zframe_streq (command, MDPW_DISCONNECT)) {
        s_worker_delete(worker, 0);
	} else {
        zclock_log ("E: invalid input message");
        zmsg_dump (msg);
    }
    free (command);
    zmsg_destroy (&msg);
}
Exemplo n.º 2
0
static void
s_worker_process (broker_t *self, zframe_t *sender, zmsg_t *msg)
{
    assert (zmsg_size (msg) >= 1);     //  At least, command

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

    if (zframe_streq (command, MDPW_READY)) {
        if (worker_ready)               //  Not first command in session
            s_worker_delete (self, worker, 1);
        else
        if (zframe_size (sender) >= 4  //  Reserved service name
        &&  memcmp (zframe_data (sender), "mmi.", 4) == 0)
            s_worker_delete (self, worker, 1);
        else {
            //  Attach worker to service and mark as idle
            zframe_t *service_frame = zmsg_pop (msg);
            worker->service = s_service_require (self, service_frame);
            worker->service->workers++;
            s_worker_waiting (self, worker);
            zframe_destroy (&service_frame);
        }
    }
    else
    if (zframe_streq (command, MDPW_REPLY)) {
        if (worker_ready) {
            //  Remove & save client return envelope and insert the
            //  protocol header and service name, then rewrap envelope.
            zframe_t *client = zmsg_unwrap (msg);
            zmsg_pushstr (msg, worker->service->name);
            zmsg_pushstr (msg, MDPC_CLIENT);
            zmsg_wrap (msg, client);
            zmsg_send (&msg, self->socket);
            s_worker_waiting (self, worker);
        }
        else
            s_worker_delete (self, worker, 1);
    }
    else
    if (zframe_streq (command, MDPW_HEARTBEAT)) {
        if (worker_ready)
            worker->expiry = zclock_time () + HEARTBEAT_EXPIRY;
        else
            s_worker_delete (self, worker, 1);
    }
    else
    if (zframe_streq (command, MDPW_DISCONNECT))
        s_worker_delete (self, worker, 0);
    else {
        zclock_log ("E: invalid input message");
        zmsg_dump (msg);
    }
    free (command);
    zmsg_destroy (&msg);
}
Exemplo n.º 3
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);
}
Exemplo n.º 4
0
static void
s_broker_worker_msg(broker_t *self, zframe_t *sender, zmsg_t *msg)
{
	assert(zmsg_size(msg) >= 1);

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

	if (zframe_streq(command, MDPW_READY)){
		if (worker_ready)
			s_worker_delete(worker, 1);
		else 
		if (zframe_size(sender) >= 4 && memcmp(zframe_data(sender), "mmi.", 4) == 0)
			s_worker_delete(worker, 1);
		else {
			zframe_t *service_frame = zmsg_pop(msg);
			worker->service = s_service_require(self, service_frame);
			worker->service->workers++;
			s_worker_waiting(worker);
			zframe_destroy(&service_frame);
		}
	}
	else
	if (zframe_streq(command, MDPW_REPLY)){
		if (worker_ready){
			zframe_t *client = zmsg_unwrap(msg);
			zmsg_pushstr(msg, worker->service->name);
			zmsg_pushstr(msg, MDPC_CLIENT);
			zmsg_wrap(msg, client);
			zmsg_send(&msg, self->socket);
			s_worker_waiting(worker);
		}
		else 
			s_worker_delete(worker, 1);
	}
	else
	if (zframe_streq(command, MDPW_HEARTBEAT)){
		if (worker_ready)
			worker->expiry = zclock_time() + HEARTBEAT_EXPIRY;
		else
			s_worker_delete(worker, 1);
	}
	else
	if (zframe_streq(command, MDPW_DISCONNECT))
		s_worker_delete(worker, 0);
	else {
		zclock_log("E: invalid input message");
		zmsg_dump(msg);
	}
	free(command);
	zmsg_destroy(&msg);

}
Exemplo n.º 5
0
static void
handle_ready (client_t *self)
{
    mdp_msg_t *msg = self->message;
    const char *service_name = mdp_msg_service(msg);
    // zsys_debug("handle_ready: service=%s\n", service_name);
    zframe_t *routing_id = mdp_msg_routing_id(msg);
    assert(routing_id);
    char *identity = zframe_strhex(routing_id);
    int worker_ready = (zhash_lookup(self->server->workers, identity) != NULL);
    free(identity);

    worker_t *worker = s_worker_require(self->server, routing_id);
    
    if (worker_ready)   // Not first command in session.
        s_worker_delete(worker, 1);
    else {
        service_t *service = s_service_require(self->server, service_name);
        worker->service = service;
        zlist_append(service->broker->waiting, worker);
        zlist_append(service->waiting, worker);
        worker->service->workers++;
        s_service_dispatch(service);
    }
}
Exemplo n.º 6
0
static void
delete_worker (client_t *self)
{
    mdp_msg_t *msg = self->message;
    zframe_t *routing_id = mdp_msg_routing_id(msg);
    assert(routing_id);
    char *identity = zframe_strhex(routing_id);
    worker_t *worker = (worker_t *) zhash_lookup(self->server->workers, identity);
    free(identity);
    if (worker != NULL)
        s_worker_delete(worker, 0);
}
Exemplo n.º 7
0
static void
s_broker_purge(broker_t *self)
{
	worker_t *worker = (worker_t *)zlist_first(self->waiting);
	while(worker){
		if (zclock_time() < worker->expiry)
			break;
		if (self->verbose)
			zclock_log("I: deleting expired worker: %s", worker->id_string);

		s_worker_delete(worker, 0);
		worker = (worker_t *)zlist_first(self->waiting);
	}
}
Exemplo n.º 8
0
static void
s_broker_purge (broker_t *self)
{
    worker_t *worker = (worker_t *) zlist_first (self->waiting);
    while (worker) {
        if (zclock_time () < worker->expiry)
            break;                  //  Worker is alive, we're done here
        if (self->verbose)
            zclock_log ("I: deleting expired worker: %s",
                        worker->identity);

        s_worker_delete (worker, 0);
        worker = (worker_t *) zlist_first (self->waiting);
    }
}
Exemplo n.º 9
0
static void
s_broker_purge_workers (broker_t *self)
{
    worker_t *worker = zlist_first (self->waiting);
    while (worker) {
        if (!s_worker_expired (worker))
            break;              //  Worker is alive, we're done here
        if (self->verbose)
            s_console ("I: deleting expired worker: %s", 
                worker->identity);

        s_worker_delete (self, worker, 0);
        worker = zlist_first (self->waiting);
    }
}
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;
}