/** * Executes the broker * * @throws \Exception */ public function execute() { // Ensure that the socket connections have been made. if (!$this->clientChannel || !$this->workerChannel) { throw new \Exception("Please run 'connect' before executing the broker!"); } // Some initialization $read = array(); $write = array(); $heartbeatAt = microtime(true) + $this->config->getInterval(); // Main loop while (true) { $poll = new ZMQPoll(); $poll->add($this->workerChannel, ZMQ::POLL_IN); // Poll the client channel only if we have available workers if ($this->queue->size()) { $poll->add($this->clientChannel, ZMQ::POLL_IN); } // Get all the events and if any events occurred process them. $events = $poll->poll($read, $write, $this->config->getInterval() * 1000); if ($events > 0) { foreach ($read as $socket) { $message = new MultipartMessage($socket); $message->recv(); // Handle worker activity on backend if ($socket === $this->workerChannel) { $identity = $message->unwrap(); $this->handleMessage($message, $identity); } else { // Now get next client request, route to next worker $identity = $this->queue->getWorker(); $message->wrap($identity); $message->setSocket($this->workerChannel)->send(); } } $heartbeatAt = $this->validateQueue($heartbeatAt); } } }
/** * @param WorkerInterface $worker * @throws \Exception */ public function execute(WorkerInterface $worker) { // Ensure that the socket connections have been made. if (!$this->workerProcess) { throw new \Exception("Please run 'connect' before executing the worker!"); } // Some initialization $read = array(); $write = array(); $heartbeatAt = microtime(true) + $this->config->getInterval(); $poll = new ZMQPoll(); $poll->add($this->workerProcess, ZMQ::POLL_IN); $liveness = $this->config->getLiveness(); $interval = $this->config->getInitInterval(); // Main loop while (true) { $events = $poll->poll($read, $write, $this->config->getInterval() * 1000); if ($events) { // Get message // - 3-part envelope + content -> request // - 1-part "HEARTBEAT" -> heartbeat $message = new MultipartMessage($this->workerProcess); $message->recv(); if ($message->parts() == 3) { $this->logger->info("({$this->identity}) Responding To Message", array($message->body())); $response = $worker->run($message->body()); $message->setBody($response); $message->send(); $liveness = $this->config->getLiveness(); } elseif ($message->parts() == 1 && $message->body() == 'HEARTBEAT') { $this->logger->info("({$this->identity}) Got heartbeat from server!"); $liveness = $this->config->getLiveness(); } else { $this->logger->error("({$this->identity}) Invalid Message!", array($message->__toString())); } $interval = $this->config->getInitInterval(); } elseif (--$liveness == 0) { $this->logger->warning("({$this->identity}) Heartbeat failure! Can't reach queue!"); $this->logger->warning("({$this->identity}) Reconnecting in {$this->config->getInterval()} seconds!"); usleep($this->config->getInterval() * 1000 * 1000); if ($interval < $this->config->getMaxInterval()) { $interval *= 2; } $this->connect($this->context); $poll->clear(); $poll->add($this->workerProcess, ZMQ::POLL_IN); $liveness = $this->config->getLiveness(); } // Send a heartbeat $heartbeatAt = $this->sendHeartbeat($heartbeatAt); } }