예제 #1
0
 def _on_close(self, method_frame):
     LOGGER.warning('Received Channel.Close, closing: %r', method_frame)
     if not self.connection.is_closed:
         self._send_method(spec.Channel.CloseOk(), None, False)
     self._set_state(self.CLOSED)
     self._cleanup()
     if method_frame is None:
         raise exceptions.ChannelClosed(0, 'Not specified')
     else:
         raise exceptions.ChannelClosed(method_frame.method.reply_code,
                                        method_frame.method.reply_text)
예제 #2
0
    def basic_publish(self, exchange, routing_key, body,
                      properties=None, mandatory=False, immediate=False):
        """Publish to the channel with the given exchange, routing key and body.
        For more information on basic_publish and what the parameters do, see:

        http://www.rabbitmq.com/amqp-0-9-1-reference.html#basic.publish

        :param exchange: The exchange to publish to
        :type exchange: str or unicode
        :param routing_key: The routing key to bind on
        :type routing_key: str or unicode
        :param body: The message body
        :type body: str or unicode
        :param pika.spec.BasicProperties properties: Basic.properties
        :param bool mandatory: The mandatory flag
        :param bool immediate: The immediate flag

        """
        if not self.is_open:
            raise exceptions.ChannelClosed()
        if immediate:
            LOGGER.warning('The immediate flag is deprecated in RabbitMQ')
        if isinstance(body, unicode):
            body = body.encode('utf-8')
        properties = properties or spec.BasicProperties()
        self._send_method(spec.Basic.Publish(exchange=exchange,
                                             routing_key=routing_key,
                                             mandatory=mandatory,
                                             immediate=immediate),
                          (properties, body))
예제 #3
0
    def close(self, reply_code=0, reply_text="Normal Shutdown"):
        """Will invoke a clean shutdown of the channel with the AMQP Broker.

        :param int reply_code: The reply code to close the channel with
        :param str reply_text: The reply text to close the channel with

        """

        LOGGER.info('Channel.close(%s, %s)', reply_code, reply_text)
        if not self.is_open:
            raise exceptions.ChannelClosed()

        # Cancel the generator if it's running
        if self._generator:
            self.cancel()

        # If there are any consumers, cancel them as well
        if self._consumers:
            LOGGER.debug('Cancelling %i consumers', len(self._consumers))
            for consumer_tag in self._consumers.keys():
                self.basic_cancel(consumer_tag=consumer_tag)
        self._set_state(self.CLOSING)
        self._rpc(spec.Channel.Close(reply_code, reply_text, 0, 0), None,
                  [spec.Channel.CloseOk])
        self._set_state(self.CLOSED)
        self._cleanup()
예제 #4
0
    def close(self, reply_code=0, reply_text="Normal Shutdown"):
        if self.is_closed:
            raise exceptions.ChannelClosed('Already closed: %s' % self)

        LOGGER.info('Closing channel (%s): %r on %s', reply_code, reply_text,
                    self)

        for consumer_tag in dictkeys(self._consumers):
            self.basic_cancel(consumer_tag=consumer_tag)
        self.is_closed = True
        return self.rpc(spec.Channel.Close(reply_code, reply_text, 0, 0),
                        [spec.Channel.CloseOk])
예제 #5
0
 def channel_closed(self, channel, reply_code, reply_text):
     # enter the closed state
     self.__closed = exceptions.ChannelClosed(reply_code, reply_text)
     # errback all pending calls
     for d in self.__calls:
         d.errback(self.__closed)
     # close all open queues
     for consumers in self.__consumers.values():
         for c in consumers:
             c.close(self.__closed)
     # release references to stored objects
     self.__calls = set()
     self.__consumers = {}
예제 #6
0
    def basic_reject(self, delivery_tag=None, requeue=True):
        """Reject an incoming message. This method allows a client to reject a
        message. It can be used to interrupt and cancel large incoming messages,
        or return untreatable messages to their original queue.

        :param int delivery-tag: The server-assigned delivery tag
        :param bool requeue: If requeue is true, the server will attempt to
                             requeue the message. If requeue is false or the
                             requeue attempt fails the messages are discarded or
                             dead-lettered.

        """
        if not self.is_open:
            raise exceptions.ChannelClosed()
        return self._send_method(spec.Basic.Reject(delivery_tag, requeue))
예제 #7
0
파일: channel.py 프로젝트: Niklas9/pika
    def close(self, reply_code=0, reply_text="Normal Shutdown"):
        """Will invoke a clean shutdown of the channel with the AMQP Broker.

        :param int reply_code: The reply code to close the channel with
        :param str reply_text: The reply text to close the channel with

        """
        if not self.is_open:
            raise exceptions.ChannelClosed()
        LOGGER.info('Channel.close(%s, %s)', self._reply_code, self._reply_text)
        self._set_state(self.CLOSING)
        self._reply_code, self._reply_text = reply_code, reply_text
        LOGGER.debug('Cancelling %i consumers', len(self._consumers))
        for consumer_tag in self._consumers.keys():
            self.basic_cancel(consumer_tag)
        self._shutdown()
예제 #8
0
파일: channel.py 프로젝트: pierremarc/pika
    def basic_consume(self,
                      consumer_callback,
                      queue='',
                      no_ack=False,
                      exclusive=False,
                      consumer_tag=None):
        """
        Sends the AMQP command Basic.Consume to the broker and binds messages
        for the consumer_tag to the consumer callback. If you do not pass in
        a consumer_tag, one will be automatically generated for you. Returns
        the consumer tag.

        For more information on basic_consume, see:
        http://www.rabbitmq.com/amqp-0-9-1-reference.html#basic.consume
        """
        # If a consumer tag was not passed, create one
        if not consumer_tag:
            consumer_tag = 'ctag%i.%i' % (self.channel_number,
                                          len(self._consumers))

        # Make sure we've not already registered this consumer tag
        if consumer_tag in self._consumers:
            raise exceptions.DuplicateConsumerTag(consumer_tag)

        # The consumer tag has not been used before, add it to our consumers
        self._consumers[consumer_tag] = consumer_callback

        # Setup a list for appending frames into
        self._pending[consumer_tag] = list()

        # Send our Basic.Consume RPC call
        try:
            self.transport.rpc(
                spec.Basic.Consume(queue=queue,
                                   consumer_tag=consumer_tag,
                                   no_ack=no_ack,
                                   exclusive=exclusive),
                self.transport._on_event_ok, [spec.Basic.ConsumeOk])
        except exceptions.ChannelClosed, e:
            del (self._consumers[consumer_tag])
            del (self._pending[consumer_tag])
            raise exceptions.ChannelClosed(e)
예제 #9
0
    def basic_ack(self, delivery_tag=0, multiple=False):
        """Acknowledge one or more messages. When sent by the client, this
        method acknowledges one or more messages delivered via the Deliver or
        Get-Ok methods. When sent by server, this method acknowledges one or
        more messages published with the Publish method on a channel in
        confirm mode. The acknowledgement can be for a single message or a
        set of messages up to and including a specific message.

        :param int delivery-tag: The server-assigned delivery tag
        :param bool multiple: If set to True, the delivery tag is treated as
                              "up to and including", so that multiple messages
                              can be acknowledged with a single method. If set
                              to False, the delivery tag refers to a single
                              message. If the multiple field is 1, and the
                              delivery tag is zero, this indicates
                              acknowledgement of all outstanding messages.
        """
        if not self.is_open:
            raise exceptions.ChannelClosed()
        return self._send_method(spec.Basic.Ack(delivery_tag, multiple))
예제 #10
0
    def basic_nack(self, delivery_tag=None, multiple=False, requeue=True):
        """This method allows a client to reject one or more incoming messages.
        It can be used to interrupt and cancel large incoming messages, or
        return untreatable messages to their original queue.

        :param int delivery-tag: The server-assigned delivery tag
        :param bool multiple: If set to True, the delivery tag is treated as
                              "up to and including", so that multiple messages
                              can be acknowledged with a single method. If set
                              to False, the delivery tag refers to a single
                              message. If the multiple field is 1, and the
                              delivery tag is zero, this indicates
                              acknowledgement of all outstanding messages.
        :param bool requeue: If requeue is true, the server will attempt to
                             requeue the message. If requeue is false or the
                             requeue attempt fails the messages are discarded or
                             dead-lettered.

        """
        if not self.is_open:
            raise exceptions.ChannelClosed()
        return self._send_method(spec.Basic.Nack(delivery_tag, multiple,
                                                 requeue))
예제 #11
0
    def basic_publish(self,
                      exchange,
                      routing_key,
                      body,
                      properties=None,
                      mandatory=False,
                      immediate=False):
        """Publish to the channel with the given exchange, routing key and body.
        Returns a boolean value indicating the success of the operation. For 
        more information on basic_publish and what the parameters do, see:

        http://www.rabbitmq.com/amqp-0-9-1-reference.html#basic.publish

        :param exchange: The exchange to publish to
        :type exchange: str or unicode
        :param routing_key: The routing key to bind on
        :type routing_key: str or unicode
        :param body: The message body
        :type body: str or unicode
        :param pika.spec.Properties properties: Basic.properties
        :param bool mandatory: The mandatory flag
        :param bool immediate: The immediate flag

        """
        if not self.is_open:
            raise exceptions.ChannelClosed()
        if immediate:
            LOGGER.warning('The immediate flag is deprecated in RabbitMQ')
        properties = properties or spec.BasicProperties()

        if mandatory:
            self._response = None

        if isinstance(body, unicode):
            body = body.encode('utf-8')

        if self._confirmation:
            response = self._rpc(
                spec.Basic.Publish(exchange=exchange,
                                   routing_key=routing_key,
                                   mandatory=mandatory,
                                   immediate=immediate), None,
                [spec.Basic.Ack, spec.Basic.Nack], (properties, body))
            if mandatory and self._response:
                response = self._response[0]
                LOGGER.warning('Message was returned (%s): %s',
                               response.reply_code, response.reply_text)
                return False

            if isinstance(response.method, spec.Basic.Ack):
                return True
            elif isinstance(response.method, spec.Basic.Nack):
                return False
            else:
                raise ValueError('Unexpected frame type: %r', response)
        else:
            self._send_method(
                spec.Basic.Publish(exchange=exchange,
                                   routing_key=routing_key,
                                   mandatory=mandatory,
                                   immediate=immediate), (properties, body),
                False)
            if mandatory:
                if self._response:
                    response = self._response[0]
                    LOGGER.warning('Message was returned (%s): %s',
                                   response.reply_code, response.reply_text)
                    return False
                return True
예제 #12
0
    def test_channel_closed_repr(self):
        exc = exceptions.ChannelClosed(200, 'all is swell')

        self.assertEqual(repr(exc), "ChannelClosed: (200) 'all is swell'")
예제 #13
0
 def test_channel_closed_properties_kwargs(self):
     exc = exceptions.ChannelClosed(reply_code=9, reply_text='kwargs abcd')
     self.assertEqual(exc.reply_code, 9)
     self.assertEqual(exc.reply_text, 'kwargs abcd')
예제 #14
0
 def test_channel_closed_properties_positional_args(self):
     exc = exceptions.ChannelClosed(9, 'args abcd')
     self.assertEqual(exc.reply_code, 9)
     self.assertEqual(exc.reply_text, 'args abcd')
예제 #15
0
 def _validate_connection_and_channel(self):
     if self.connection.is_closed():
         raise exceptions.ConnectionClosed()
     if self.is_closed:
         raise exceptions.ChannelClosed()
예제 #16
0
 def _validate_channel_and_callback(self, callback):
     if not self.is_open:
         raise exceptions.ChannelClosed()
     if callback is not None and not is_callable(callback):
         raise ValueError('callback must be a function or method')
예제 #17
0
    def _on_channel_close(self, channel, reply_code, reply_text):
        self._evt_closed.set()

        if self._current_future:
            self._current_future.set_exception(
                pika_exceptions.ChannelClosed(reply_code, reply_text))
예제 #18
0
 def _on_close(self, method_frame):
     LOGGER.warning('Received Channel.Close, closing: %r', method_frame)
     self._send_method(spec.Channel.CloseOk(), None, False)
     self._set_state(self.CLOSED)
     raise exceptions.ChannelClosed(self._reply_code, self._reply_text)