/** Push message into master. This is generally called when a worker needs to send messaes to a master * This function runs as a seperate thread */ void MasterClient::Pusher() { socket_t socket(*ctx_, ZMQ_PUSH); #ifdef ZMQ_LINGER // wait for 2 seconds after socket close int linger_period = SOCK_LINGER_TIME; socket.setsockopt(ZMQ_LINGER, &linger_period, sizeof(linger_period)); #endif try { socket.connect(endpoint_.c_str()); } catch (zmq::error_t err) { ostringstream msg; msg << "connect to master at " << endpoint_.c_str() << " failed: "<< err.what(); LOG_ERROR(msg.str()); return; } LOG_DEBUG("Connected to master at %s", endpoint_.c_str()); while (true) { unique_lock<mutex> lock(message_queue_mutex_); while (message_queue_.empty()) { message_queue_empty_.wait(lock); if (!running_) { return; } } if (!running_) { // delete this if we want to // process remaining messages // before shutting down return; } // MasterRequest class contains message structure from worker to master MasterRequest req = message_queue_.front(); message_queue_.pop_front(); lock.unlock(); message_t zmq_req(req.ByteSize()); req.SerializeToArray(zmq_req.data(), zmq_req.size()); //notify observers Notify(req); try { socket.send(zmq_req); } catch (zmq::error_t err) { fprintf(stderr, "send to master %s failed: %s", endpoint_.c_str(), err.what()); return; } } }
/** This function sends a message (or task) in a queue to a worker. This is called from a master side * @return NULL */ void WorkerInfo::Pusher() { socket_t socket(*ctx_, ZMQ_PUSH); #ifdef ZMQ_LINGER int linger_period = SOCK_LINGER_TIME; socket.setsockopt(ZMQ_LINGER, &linger_period, sizeof(linger_period)); #endif try { socket.connect(endpoint_.c_str()); } catch (zmq::error_t err) { ostringstream msg; msg << "connect to worker " << endpoint_ << " with error - " << err.what(); fprintf(stderr, "%s\n", msg.str().c_str()); return; } while (true) { unique_lock<mutex> lock(message_queue_mutex_); while (message_queue_.empty()) { message_queue_empty_.wait(lock); // to process packets that were queued right before running_ set to false if (!running_ && message_queue_.empty()) { return; } } // to process packets that were queued right before running_ set to false if (!running_ && message_queue_.empty()) { // delete this if we want to // process remaining messages // before shutting down return; } WorkerRequest req = message_queue_.front(); message_queue_.pop_front(); lock.unlock(); message_t zmq_req(req.ByteSize()); req.SerializeToArray(zmq_req.data(), zmq_req.size()); try { socket.send(zmq_req); } catch (zmq::error_t err) { fprintf(stderr, "send to worker %s failed %s\n", endpoint_.c_str(), err.what()); return; } } }