示例#1
0
 /**
  * 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));
 }
示例#2
0
 /**
  * Get the next available channel ID.
  *
  * @throws ChannelException No channels are available.
  */
 private function findChannelId() : int
 {
     // first check in range [next, max] ...
     for ($channelId = $this->nextChannelId; $channelId <= $this->tune->channelMax; ++$channelId) {
         if (!isset($this->channels[$channelId])) {
             $this->nextChannelId = $channelId + 1;
             return $channelId;
         }
     }
     // then check in range [min, next) ...
     for ($channelId = 1; $channelId < $this->nextChannelId; ++$channelId) {
         if (!isset($this->channels[$channelId])) {
             $this->nextChannelId = $channelId + 1;
             return $channelId;
         }
     }
     throw ChannelException::noAvailableChannels();
 }
示例#3
0
 /**
  * @recoil-coroutine
  */
 public function onCloseByBroker(ChannelCloseFrame $frame) : Generator
 {
     $this->connectionManager->removeChannel($this->channelId);
     $exception = AmqpException::create($frame->replyText, $frame->replyCode);
     // The closure was triggered by a previously sent frame. Find the
     // offending strand and resume it with an exception specific to this
     // closure ...
     if ($frame->classId && $frame->methodId) {
         $sentMethod = $frame->classId << 16 | $frame->methodId;
         ($callers =& $this->callersBySentMethod[$sentMethod]) ?? null;
         if ($callers !== null) {
             foreach ($callers as $id => $waitMethod) {
                 $strand = $this->callers[$waitMethod][$id];
                 unset($this->callers[$waitMethod][$id], $this->callersBySentMethod[$sentMethod][$id], $this->callersByWaitMethod[$waitMethod][$id]);
                 (yield Recoil::throw($strand, $exception));
                 break;
             }
         }
     }
     // Acknowledge the closure ...
     $frame = new ChannelCloseOkFrame();
     $frame->frameChannelId = $this->channelId;
     (yield $this->transport->write($frame));
     // Procee to the regular on-close logic. To all remaining callers and
     // listeners this is an unexpected closure ...
     (yield $this->onClose(ChannelException::closedUnexpectedly($this->channelId, $exception)));
 }