/** * @inheritdoc */ public function listen($queue, callable $callback, array $options = []) { $options = array_merge($this->defaultConfig['listener'], $options); $connectionConfig = $this->getConfig('connection', $this->config['queues'][$queue]['connection']); $ackAt = isset($options['multi_ack']) ? ceil($connectionConfig['prefetch_count'] / 2) : 0; try { $queue = $this->getQueue($queue); $acknowledged = 0; $queue->consume(\Closure::bind(function (\AMQPEnvelope $envelope) use($callback, $queue, $ackAt, &$acknowledged) { $result = new Message\Result(); call_user_func($callback, Helper\Message::convert($envelope), $result); if ($result->getStatus()) { if ($ackAt > 1) { if (0 == ++$acknowledged % $ackAt) { $queue->ack($envelope->getDeliveryTag(), AMQP_MULTIPLE); } } else { $queue->ack($envelope->getDeliveryTag()); } } else { $queue->nack($envelope->getDeliveryTag(), $result->isRequeue() ? AMQP_REQUEUE : AMQP_NOPARAM); } if ($result->isStop()) { return false; } }, $this), Helper\Options::toFlags($options)); } catch (\Exception $e) { throw Helper\Exception::convert($e); } }