/** * Get bucket / content hash * * @param string $topic * @param string $channel * @param MessageInterface $msg * * @return array index, content, seen (boolean) */ private function hash($topic, $channel, MessageInterface $msg) { $element = "{$topic}:{$channel}:" . $msg->getPayload(); $hash = hash('adler32', $element, TRUE); list(, $val) = unpack('N', $hash); $index = $val % $this->size; $content = md5($element); $seen = isset($this->map[$index]) && $this->map[$index] === $content; return array('index' => $index, 'content' => $content, 'seen' => $seen); }
/** * Get bucket / content hash * * @param string $topic * @param string $channel * @param MessageInterface $msg * * @return array index, content, seen (boolean), mcKey */ private function hash($topic, $channel, MessageInterface $msg) { $element = "{$topic}:{$channel}:" . $msg->getPayload(); $hash = hash('adler32', $element, TRUE); list(, $val) = unpack('N', $hash); $index = $val % $this->size; $content = md5($element); $mcKey = "nsqphp:{$this->size}:{$index}"; $storedContentHash = $this->memcached->get($mcKey); $seen = $storedContentHash && $storedContentHash === $content; return array('index' => $index, 'content' => $content, 'seen' => $seen, 'mcKey' => $mcKey); }
/** * Publish message * * @param string $topic A valid topic name: [.a-zA-Z0-9_-] and 1 < length < 32 * @param MessageInterface $msg * * @throws Exception\PublishException If we don't get "OK" back from server * (for the specified number of hosts - as directed by `publishTo`) * * @return nsqphp This instance for call chaining */ public function publish($topic, MessageInterface $msg) { // pick a random $this->pubConnectionPool->shuffle(); $success = 0; $errors = array(); foreach ($this->pubConnectionPool as $conn) { /** @var $conn ConnectionInterface */ try { $this->tryFunc(function (ConnectionInterface $conn) use($topic, $msg, &$success, &$errors) { $conn->write($this->writer->publish($topic, $msg->getPayload())); $frame = $this->reader->readFrame($conn); while ($this->reader->frameIsHeartbeat($frame)) { $conn->write($this->writer->nop()); $frame = $this->reader->readFrame($conn); } if ($this->reader->frameIsResponse($frame, 'OK')) { $success++; } else { $errors[] = $frame['error']; } }, $conn, 2); } catch (\Exception $e) { $errors[] = $e->getMessage(); } if ($success >= $this->pubSuccessCount) { break; } } if ($success < $this->pubSuccessCount) { throw new Exception\PublishException(sprintf('Failed to publish message; required %s for success, achieved %s. Errors were: %s', $this->pubSuccessCount, $success, implode(', ', $errors))); } return $this; }