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)
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)
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)
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)
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]))