/** * @param string $title * @param boolean $durable * @param boolean $autoDelete * @param array $arguments * @throws Exception */ public function createQueue($title, $durable = false, $autoDelete = false, $arguments = null) { if (!$this->channel) { throw new Exception("Channel didn't created"); } $this->channel->queue_declare($title, false, $durable, false, $autoDelete, false, $arguments); $this->channel->basic_qos(null, 1, null); }
/** * Infinite loop: Listens for messages from the queue and sends them to the callback. * * @param callback $callback */ public function listen($callback) { $this->channel->basic_qos(null, 1, null); $this->channel->basic_consume(self::QUEUE_NAME, '', false, true, false, false, $callback); while ($this->channel->callbacks) { $this->channel->wait(); } }
/** * Creates (if not yet created) and returns an AMQP channel. * * @return \PhpAmqpLib\Channel\AMQPChannel */ protected function getChannel() { if (null === $this->channel) { $this->channel = $this->connection->channel(); $this->channel->queue_declare($this->queueName, false, false, false, false); $this->channel->basic_qos(null, 1, null); } return $this->channel; }
/** * @return AMQPChannel */ public function getAmqpChannel() { if ($this->amqp_channel) { return $this->amqp_channel; } $this->amqp_channel = $this->connection->getAmqpConnection()->channel(); $this->amqp_channel->queue_declare($this->queue_config['queue_name'], false, $is_durable = true, false, false); $this->amqp_channel->basic_qos(null, $this->queue_config['fetch_count'], null); return $this->amqp_channel; }
/** * @param AMQPStreamConnection $connection * @param EventBusInterface $eventBus * @param DeserializerLocatorInterface $deserializerLocator * @param StringLiteral $consumerTag * @param StringLiteral $exchangeName * @param StringLiteral $queueName * @param int $delay */ public function __construct(AMQPStreamConnection $connection, EventBusInterface $eventBus, DeserializerLocatorInterface $deserializerLocator, StringLiteral $consumerTag, StringLiteral $exchangeName, StringLiteral $queueName, $delay = 0) { $this->connection = $connection; $this->channel = $connection->channel(); $this->channel->basic_qos(0, 4, true); $this->eventBus = $eventBus; $this->deserializerLocator = $deserializerLocator; $this->queueName = $queueName; $this->consumerTag = $consumerTag; $this->exchangeName = $exchangeName; $this->delay = $delay; $this->declareQueue(); $this->registerConsumeCallback(); }
public function work($maxMessages = null, $timeOut = null) { $callback = function (AMQPMessage $message) { $this->handle($message); }; $this->channel->basic_qos(null, 1, null); $this->channel->basic_consume($this->queue, '', false, false, false, false, $callback); // Loop infinitely (or up to $count) to execute tasks while (count($this->channel->callbacks) && (is_null($maxMessages) || $maxMessages > 0)) { $this->channel->wait(); if (!is_null($maxMessages)) { $maxMessages--; } } }
/** * Starts to listen a queue for incoming messages. * @param string $queueName The AMQP queue * @param array $handlers Array of handler class instances * @return bool */ public function listenToQueue($queueName, array $handlers) { $this->queueName = $queueName; /* Look for handlers */ $handlersMap = array(); foreach ($handlers as $handlerClassPath) { if (!class_exists($handlerClassPath)) { $handlerClassPath = "RabbitManager\\Handlers\\{$handlerClassPath}"; if (!class_exists($handlerClassPath)) { $this->logger->addError("Class {$handlerClassPath} was not found!"); return false; } } $handlerOb = new $handlerClassPath(); $classPathParts = explode("\\", $handlerClassPath); $handlersMap[$classPathParts[count($classPathParts) - 1]] = $handlerOb; } /* Create queue */ $this->channel->queue_declare($queueName, false, true, false, false); /* Start consuming */ $this->channel->basic_qos(null, 1, null); $this->channel->basic_consume($queueName, '', false, false, false, false, function ($amqpMsg) use($handlersMap) { $msg = Message::fromAMQPMessage($amqpMsg); Broker::handleMessage($msg, $handlersMap); }); $this->logger->addInfo("Starting consumption of queue {$queueName}"); /* Iterate until ctrl+c is received... */ while (count($this->channel->callbacks)) { $this->channel->wait(); } }
public function actionIndex() { Yii::info('Started email task', __METHOD__); $this->setupConnection(); echo '[*] Waiting for messages. To exit press CTRL+C', "\n"; $this->channel->basic_qos(null, 1, null); $this->channel->basic_consume($this->queue, '', false, false, false, false, [$this, 'processEmail']); while (count($this->channel->callbacks)) { $this->channel->wait(); } echo 'Shutting down...', "\n"; Yii::info('Shutting down...', __METHOD__); Yii::trace('Disconnecting...', __METHOD__); $this->channel->close(); $this->connection->close(); return self::EXIT_CODE_NORMAL; }
/** * Set the Quality Of Service settings for the given channel. * * Specify the amount of data to prefetch in terms of window size (octets) * or number of messages from a queue during a AMQPQueue::consume() or * AMQPQueue::get() method call. The client will prefetch data up to size * octets or count messages from the server, whichever limit is hit first. * Setting either value to 0 will instruct the client to ignore that * particular setting. A call to AMQPChannel::qos() will overwrite any * values set by calling AMQPChannel::setPrefetchSize() and * AMQPChannel::setPrefetchCount(). If the call to either * AMQPQueue::consume() or AMQPQueue::get() is done with the AMQP_AUTOACK * flag set, the client will not do any prefetching of data, regardless of * the QOS settings. * * @param integer $size The window size, in octets, to prefetch. * @param integer $count The number of messages to prefetch. * * @throws AMQPConnectionException If the connection to the broker was lost. * * @return bool TRUE on success or FALSE on failure. */ public function qos($size, $count) { try { $this->channel->basic_qos($size, $count, false); } catch (Exception $e) { return false; } return true; }
/** * @throws \yii\base\InvalidConfigException */ protected function initQueue() { /** @var Queue */ $this->queue = Instance::ensure($this->queue, Queue::class); $this->channel = $this->queue->getChannel(); $this->channel->basic_qos($this->prefetchSize, $this->prefetchCount, null); /** * Message consume callback wrapper * * @param AMQPMessage $message * * @throws Exception */ $callback = function (AMQPMessage $message) { $this->messageCallback($message); }; $this->consumerTag = $this->channel->basic_consume($this->queue->name, '', false, false, $this->noAck, false, $callback); }
/** * Initializes the message queue class * * @param \PhpAmqpLib\Channel\AMQPChannel $channel AMQP channel * @param string $queue Message queue name * @throws \Aimeos\MW\MQueue\Exception */ public function __construct(\PhpAmqpLib\Channel\AMQPChannel $channel, $queue) { try { $channel->queue_declare($queue, false, true, false, false); $channel->basic_qos(null, 1, null); } catch (\Exception $e) { throw new \Aimeos\MW\MQueue\Exception($e->getMessage()); } $this->channel = $channel; $this->queue = $queue; }
private function init() { $this->connection = new AMQPStreamConnection($this->host, $this->port, $this->user, $this->pass, '/', false, 'AMQPLAIN', null, 'en_US', 0); $this->channel = $this->connection->channel(); $this->channel->queue_declare(self::QUEUE_NAME, false, true, false, false, false); $this->channel->exchange_declare(self::EXCHEAGE_NAME, 'direct'); $this->channel->queue_bind(self::QUEUE_NAME, self::EXCHEAGE_NAME); $this->channel->queue_declare(self::QUEUE_WITH_DELAY_NAME, false, true, false, false, false, array('x-message-ttl' => array('I', self::DELAY * 1000), 'x-dead-letter-exchange' => array('S', self::EXCHEAGE_NAME))); $this->channel->exchange_declare(self::EXCHANGE_WITH_DELAY_NAME, 'direct'); $this->channel->queue_bind(self::QUEUE_WITH_DELAY_NAME, self::EXCHANGE_WITH_DELAY_NAME); $this->channel->basic_qos(null, 1, null); register_shutdown_function([$this, 'shutdown'], $this->channel, $this->connection); }
/** * Setup consumer. */ protected function setUpConsumer() { if (isset($this->exchangeOptions['name'])) { $this->channel->exchange_declare($this->exchangeOptions['name'], $this->exchangeOptions['type'], $this->exchangeOptions['passive'], $this->exchangeOptions['durable'], $this->exchangeOptions['auto_delete'], $this->exchangeOptions['internal'], $this->exchangeOptions['nowait'], $this->exchangeOptions['arguments'], $this->exchangeOptions['ticket']); if (!empty($this->consumerOptions['qos'])) { $this->channel->basic_qos($this->consumerOptions['qos']['prefetch_size'], $this->consumerOptions['qos']['prefetch_count'], $this->consumerOptions['qos']['global']); } } list($queueName, , ) = $this->channel->queue_declare($this->queueOptions['name'], $this->queueOptions['passive'], $this->queueOptions['durable'], $this->queueOptions['exclusive'], $this->queueOptions['auto_delete'], $this->queueOptions['nowait'], $this->queueOptions['arguments'], $this->queueOptions['ticket']); if (isset($this->exchangeOptions['name'])) { $this->channel->queue_bind($queueName, $this->exchangeOptions['name'], $this->routingKey); } $this->channel->basic_consume($queueName, $this->getConsumerTag(), false, false, false, false, array($this, 'processMessage')); }
/** * Подключение к серверу * * @param bool $reconnect пепеподключение, если нужно * @return bool */ protected function _connect($reconnect = true) { // уже подключены if (!$reconnect && $this->_connected) { return $this->_connected; } // отключаемся $this->_disconnect(); try { // соединение $this->_Connection = new AMQPStreamConnection($this->_config['server']['host'], $this->_config['server']['port'], $this->_config['server']['user'], $this->_config['server']['password'], $this->_config['server']['vhost']); // канал $this->_Channel = $this->_Connection->channel(); // можно отправить в очередь отдельно для каждого обработчика if (!empty($this->_config['qos'])) { $this->_Channel->basic_qos(null, $this->_config['qos'], null); } $this->_declare(); $this->_connected = true; } catch (\Exception $e) { throw new Exception('Could not connect: ' . $e->getMessage(), $e->getCode()); } return $this->_connected; }
/** * @param ConsumerContainer $consumerContainer * * @throws ConsumerException */ private function registerConsumerContainer(ConsumerContainer $consumerContainer) { $consumerName = $consumerContainer->getConsumerName(); if (isset($this->consumerContainers[$consumerName])) { $currentConsumer = $this->consumerContainers[$consumerName]; throw new ConsumerException(sprintf('Can not register consumer method [%s] because the consumer method [%s] already uses that name', $consumerContainer->getMethodName(), $currentConsumer->getMethodName())); } $this->channel->queue_declare($consumerName, false, true, false, false); foreach ($consumerContainer->getBindings() as $binding) { $this->channel->queue_bind($consumerName, $this->exchangeName, $binding); } $this->channel->basic_qos($consumerName, $consumerContainer->getPrefetchCount(), false); $this->channel->basic_consume($consumerName, '', false, false, false, false, function (AMQPMessage $message) use($consumerContainer) { $this->consume($consumerContainer, $message); $message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']); }); $this->consumerContainers[$consumerName] = $consumerContainer; }
/** * @test */ public function register_consumer_should_bind_queues() { $consumer = new stdClass(); $binding2 = 'binding2'; $binding1 = 'binding1'; $consumerName = 'myName'; $bindings = [$binding1, $binding2]; $containerMock = $this->prophesize(ConsumerContainer::class); $containerMock->getBindings()->willReturn($bindings); $containerMock->getConsumerName()->willReturn($consumerName); $containerMock->getPrefetchCount()->willReturn(1); $this->parser->getConsumerMethods($consumer)->willReturn([$containerMock]); $this->channel->basic_qos($consumerName, 1, false)->shouldBeCalled(); $this->channel->basic_consume($consumerName, Argument::any(), Argument::any(), Argument::any(), Argument::any(), Argument::any(), Argument::any())->shouldBeCalled(); $this->channel->queue_declare($consumerName, Argument::any(), Argument::any(), Argument::any(), Argument::any())->shouldBeCalled(); $this->channel->queue_bind($consumerName, self::EXCHANGE_NAME, $binding1)->shouldBeCalled(); $this->channel->queue_bind($consumerName, self::EXCHANGE_NAME, $binding2)->shouldBeCalled(); $this->manager->registerConsumer($consumer); }
/** * @inheritdoc */ public function qos(int $size, int $count) { $this->channel->basic_qos($size, $count, false); $this->prefechSize = $size; $this->prefetchCount = $count; }
/** * Allows to specify basic quality of service for the channel or connection. * * The queue sends messages in advance to the consumer, so that when the client finishes processing a * message, the following message is already local, rather than needing to be sent down the channel. * * Pre-fetching gives a performance improvement, so this method allows to select the prefetch window in * bytes or select a maximum number of messages. * * If prefetchSize is set, the server will send a message in advance if it is equal to or smaller in size * than the available prefetch size. By default, there's no limit. * * If isGlobal is set to true, the QoS settings will be for all the channels using the connection, instead * of only to the channel setting the QoS rules. * * By default, the message broker pushes all the queue's messages to the clients as fast as the network and * the clients allow. The consumers will balloon in memory as they buffer all the messages in their own RAM. * The queue may appear empty if you ask the broker, but there may be millions of messages unacknowledged as * they sit in the consumers, ready for processing by the client application. Prefetch messages will not be * sent to new consumers connecting to the queue. * * @see http://www.rabbitmq.com/blog/2012/05/11/some-queuing-theory-throughput-latency-and-bandwidth/ * @note This is only relevant with messages needing ack. If no-ack is set, QoS will be ignored. * * @param int $prefetchSize in bytes * @param int $prefetchCount as number of messages * @param bool $isGlobal * * @return $this */ public function setQualityOfService($prefetchSize, $prefetchCount, $isGlobal) { $this->channel->basic_qos($prefetchSize, $prefetchCount, $isGlobal); return $this; }
public function worker($callback) { $this->channel->basic_qos(null, 1, null); $this->channel->basic_consume('build_queue', '', false, false, false, false, $callback); }
/** * @param int $size * @param int $count * @param boolean $global * * @return mixed */ public function basic_qos($size, $count, $global = null) { return $this->channel->basic_qos($size, $count, $global); }
/** * @param int $prefechCount */ public function defineQoS($prefechCount = 1) { $this->channel->basic_qos(null, $prefechCount, null); $this->logger->info(sprintf('QoS defined (prefetch count: %s)!', $prefechCount)); }