/**
  * 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);
     }
 }