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