/** * Acquire an unused channel. * * @recoil-coroutine */ public function acquireChannel(Channel $channel = null) : Generator { // The connection is not open ... if ($this->state !== ConnectionState::OPEN) { throw SingleConnectionException::notOpen($this->options); } if ($channel !== null) { $channelId = $channel->id(); $channelManager = $this->channels[$channelId] ?? null; if ($channelManager === null) { throw ChannelException::notOpen($channelId); } return $channelManager; } // Check for previously released channels that can be used instead of // asking the broker for a new one ... foreach ($this->availableChannels as $channelId => $channelManager) { unset($this->availableChannels[$channelId], $this->availableChannelHeartbeats[$channelId]); return $channelManager; } $channelId = $this->findChannelId(); // Open a new channel ... $channelManager = new ChannelManager($channelId, $this, $this->transport, $this->tune->frameMax); $this->channels[$channelId] = $channelManager; (yield $channelManager->open()); return $channelManager; }
/** * Set the pre-fetch limits for consumers on this channel. * * @recoil-coroutine * * Only consumers created after setting the limits are affected. * * The pre-fetch count is the maximum number of unacknowledged messages that * are delivered to each consumer on this channel. * * The pre-fetch limit is the maximum total size of unacknowledge messages * (in bytes) that is delivered to this channel. * * This feature requires the "per_consumer_qos" broker capability. * * RabbitMQ does not support pre-fetch size limits (current as of v3.5.6). * * @param int|null $count The pre-fetch count limit (null = unlimited). * @param int|null $size The pre-fetch size limit (null = unlimited). * * @throws NotSupportedException The broker does not support this feature. * @throws ConnectionException The connection is closed. * @throws ChannelException The channel is closed. */ public function setConsumerQosLimits(int $count = null, int $size = null) : Generator { assert($size === null || $size > 0); assert($count === null || $count > 0); if ($this->channelManager === null) { throw ChannelException::notOpen($this->channelId); } elseif (!$this->features->perConsumerQos) { throw NotSupportedException::missingCapability('per-consumer QoS limits', 'per_consumer_qos'); } elseif ($size !== null && !$this->features->qosSizeLimits) { throw NotSupportedException::unsupportedFeature('pre-fetch size limits'); } $this->channelManager->setDirty(); (yield $this->channelManager->call(BasicQosFrame::create($size ?: 0, $count ?: 0, false), BasicQosOkFrame::METHOD_ID)); }
/** * Receive notification when frames of a given type are received. * * This method is generally used to receive asynchronous/push style * notifications from the broker. * * @param integer $method The method ID of the frame to wait for (*::METHOD_ID constant). * @param callable $callback The callback invoked when a matching frame is received. * * The callback signature is: * * function(Exception $exception = null, IncomingFrame $frame = null) * * If the first parameter is non-null an error has occurred. If both * parameters are null, the channel has been closed cleanly. * * @return callable A function that is invoked to cancel the listener. */ public function listen($method, callable $callback) { if ($this->state !== ChannelState::OPEN) { throw ChannelException::notOpen($this->channelId); } $id = $this->nextListenerId++; $this->listeners[$method][$id] = $callback; return function () use($method, $id) { unset($this->listeners[$method][$id]); }; }