/**
  * Checks if workers are still valid.
  *
  * @param string $heartbeatAt
  * @return mixed|string
  */
 public function validateQueue($heartbeatAt)
 {
     if (microtime(true) > $heartbeatAt) {
         $this->queue->rewind();
         while ($this->queue->valid()) {
             $message = new MultipartMessage($this->workerChannel);
             $message->setBody("HEARTBEAT");
             $message->wrap($this->queue->key(), null);
             $message->send();
             $this->queue->next();
         }
         $heartbeatAt = microtime(true) + $this->config->getInterval();
     }
     $this->queue->purgeQueue();
     return $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);
     }
 }