示例#1
0
 def test_publish_rejected(self):
     # Check that the correct exception is raised when the publication is
     # rejected.
     self.publisher._channel.publish.side_effect = pika_errs.NackError(
         [self.message])
     self.assertRaises(PublishReturned, self.publisher.publish,
                       self.message)
     self.publisher._channel.publish.side_effect = pika_errs.UnroutableError(
         [self.message])
     self.assertRaises(PublishReturned, self.publisher.publish,
                       self.message)
示例#2
0
    def _on_delivery_confirmation(self, method_frame):
        """Invoked by pika when RabbitMQ responds to a Basic.Publish RPC
        command, passing in either a Basic.Ack or Basic.Nack frame with
        the delivery tag of the message that was published. The delivery tag
        is an integer counter indicating the message number that was sent
        on the channel via Basic.Publish. Here we're just doing house keeping
        to keep track of stats and remove message numbers that we expect
        a delivery confirmation of from the list used to keep track of messages
        that are pending confirmation.

        :param pika.frame.Method method_frame: Basic.Ack or Basic.Nack frame

        """
        delivery_tag = method_frame.method.delivery_tag
        if delivery_tag not in self._deliveries:
            LOGGER.error("Delivery tag %s not found in the pending deliveries",
                         delivery_tag)
            return
        if method_frame.method.multiple:
            tags = [
                tag for tag in self._deliveries
                if tag <= delivery_tag
            ]
            tags.sort()
        else:
            tags = [delivery_tag]
        for tag in tags:
            d = self._deliveries[tag]
            del self._deliveries[tag]
            if isinstance(method_frame.method, pika.spec.Basic.Nack):
                # Broker was unable to process the message due to internal
                # error
                LOGGER.warning(
                    "Message was Nack'ed by broker: nack=%r; channel=%s;",
                    method_frame.method, self.channel_number)
                if self._puback_return is not None:
                    returned_messages = [self._puback_return]
                    self._puback_return = None
                else:
                    returned_messages = []
                d.errback(exceptions.NackError(returned_messages))
            else:
                assert isinstance(method_frame.method, pika.spec.Basic.Ack)
                if self._puback_return is not None:
                    # Unroutable message was returned
                    returned_messages = [self._puback_return]
                    self._puback_return = None
                    d.errback(exceptions.UnroutableError(returned_messages))
                else:
                    d.callback(method_frame.method)
示例#3
0
    def publish(self,
                exchange,
                routing_key,
                body,
                properties=None,
                mandatory=False,
                immediate=False):
        if self._delivery_confirmation:
            # In publisher-acknowledgments mode
            self.basic_publish(exchange=exchange,
                               routing_key=routing_key,
                               body=body,
                               properties=properties,
                               mandatory=mandatory,
                               immediate=immediate)
            conf_method = self._puback_queue.get()
            if isinstance(conf_method, spec.Basic.Nack):
                # Broker was unable to process the message due to internal
                # error
                LOGGER.warn(
                    "Message was Nack'ed by broker: nack=%r; channel=%s; "
                    "exchange=%s; routing_key=%s; mandatory=%r; "
                    "immediate=%r", conf_method, self.channel_number, exchange,
                    routing_key, mandatory, immediate)
                if self._puback_return is not None:
                    returned_messages = [self._puback_return]
                    self._puback_return = None
                else:
                    returned_messages = []
                raise exceptions.NackError(returned_messages)
            else:
                assert isinstance(conf_method, spec.Basic.Ack), (conf_method)

                if self._puback_return is not None:
                    # Unroutable message was returned
                    messages = [self._puback_return]
                    self._puback_return = None
                    raise exceptions.UnroutableError(messages)
        else:
            # In non-publisher-acknowledgments mode
            self.basic_publish(exchange=exchange,
                               routing_key=routing_key,
                               body=body,
                               properties=properties,
                               mandatory=mandatory,
                               immediate=immediate)
示例#4
0
    def publish(
            self,
            exchange,
            routing_key,
            body,  # pylint: disable=R0913
            properties=None,
            mandatory=False,
            immediate=False):

        if self._delivery_confirmation:
            self._check_called_not_from_event_loop()

            # In publisher-acknowledgments mode
            self._message_returned = False
            self._current_future = futurist.Future()

            self._execute_task(self._impl.basic_publish,
                               exchange=exchange,
                               routing_key=routing_key,
                               body=body,
                               properties=properties,
                               mandatory=mandatory,
                               immediate=immediate)

            conf_method = self._current_future.result().method

            if isinstance(conf_method, pika_spec.Basic.Nack):
                raise pika_exceptions.NackError((None, ))
            else:
                assert isinstance(conf_method,
                                  pika_spec.Basic.Ack), (conf_method)

                if self._message_returned:
                    raise pika_exceptions.UnroutableError((None, ))
        else:
            # In non-publisher-acknowledgments mode
            self._execute_task(self._impl.basic_publish,
                               exchange=exchange,
                               routing_key=routing_key,
                               body=body,
                               properties=properties,
                               mandatory=mandatory,
                               immediate=immediate)
示例#5
0
 def _on_return_delivery(self, channel, method_frame, properties, body):
     f = self._confirmations.pop(int(properties.headers.get('delivery-tag')))
     f.set_exception(exceptions.UnroutableError([body]))