def test_revive(self): exchange = Exchange("foo", "direct") chan = Channel() # reviving unbound channel is a noop. exchange.revive(chan) self.assertFalse(exchange.is_bound) self.assertIsNone(exchange._channel) bound = exchange.bind(chan) self.assertTrue(bound.is_bound) self.assertIs(bound.channel, chan) chan2 = Channel() bound.revive(chan2) self.assertTrue(bound.is_bound) self.assertIs(bound._channel, chan2)
def test_revive(self): exchange = Exchange('foo', 'direct') conn = get_conn() chan = conn.channel() # reviving unbound channel is a noop. exchange.revive(chan) self.assertFalse(exchange.is_bound) self.assertIsNone(exchange._channel) bound = exchange.bind(chan) self.assertTrue(bound.is_bound) self.assertIs(bound.channel, chan) chan2 = conn.channel() bound.revive(chan2) self.assertTrue(bound.is_bound) self.assertIs(bound._channel, chan2)
class Producer(object): """Message Producer. :param channel: Connection channel. :keyword exchange: Default exchange. :keyword routing_key: Default routing key. :keyword serializer: Default serializer. Default is `"json"`. :keyword compression: Default compression method. Default is no compression. :keyword auto_declare: Automatically declare the exchange at instantiation. Default is :const:`True`. :keyword on_return: Callback to call for undeliverable messages, when the `mandatory` or `immediate` arguments to :meth:`publish` is used. This callback needs the following signature: `(exception, exchange, routing_key, message)`. Note that the producer needs to drain events to use this feature. """ #: The connection channel used. channel = None #: Default exchange. exchange = None # Default routing key. routing_key = "" #: Default serializer to use. Default is JSON. serializer = None #: Default compression method. Disabled by default. compression = None #: By default the exchange is declared at instantiation. #: If you want to declare manually then you can set this #: to :const:`False`. auto_declare = True #: Basic return callback. on_return = None def __init__(self, channel, exchange=None, routing_key=None, serializer=None, auto_declare=None, compression=None, on_return=None): self.channel = channel self.exchange = exchange or self.exchange if self.exchange is None: self.exchange = Exchange("") self.routing_key = routing_key or self.routing_key self.serializer = serializer or self.serializer self.compression = compression or self.compression self.on_return = on_return or self.on_return if auto_declare is not None: self.auto_declare = auto_declare self.exchange = self.exchange(self.channel) if self.auto_declare: self.declare() if self.on_return: self.channel.events["basic_return"].append(self.on_return) def declare(self): """Declare the exchange. This is done automatically at instantiation if :attr:`auto_declare` is set to :const:`True`. """ if self.exchange.name: self.exchange.declare() def publish(self, body, routing_key=None, delivery_mode=None, mandatory=False, immediate=False, priority=0, content_type=None, content_encoding=None, serializer=None, headers=None, compression=None, exchange=None): """Publish message to the specified exchange. :param body: Message body. :keyword routing_key: Message routing key. :keyword delivery_mode: See :attr:`delivery_mode`. :keyword mandatory: Currently not supported. :keyword immediate: Currently not supported. :keyword priority: Message priority. A number between 0 and 9. :keyword content_type: Content type. Default is autodetect. :keyword content_encoding: Content encoding. Default is autodetect. :keyword serializer: Serializer to use. Default is autodetect. :keyword headers: Mapping of arbitrary headers to pass along with the message body. :keyword exchange: Override the exchange. Note that this exchange must have been declared. """ headers = headers or {} if routing_key is None: routing_key = self.routing_key if compression is None: compression = self.compression body, content_type, content_encoding = self._prepare( body, serializer, content_type, content_encoding, compression, headers) message = self.exchange.Message(body, delivery_mode, priority, content_type, content_encoding, headers=headers) return self.exchange.publish(message, routing_key, mandatory, immediate, exchange=exchange) def revive(self, channel): """Revive the producer after connection loss.""" self.channel = channel self.exchange.revive(channel) def _prepare(self, body, serializer=None, content_type=None, content_encoding=None, compression=None, headers=None): # No content_type? Then we're serializing the data internally. if not content_type: serializer = serializer or self.serializer (content_type, content_encoding, body) = encode(body, serializer=serializer) else: # If the programmer doesn't want us to serialize, # make sure content_encoding is set. if isinstance(body, unicode): if not content_encoding: content_encoding = 'utf-8' body = body.encode(content_encoding) # If they passed in a string, we can't know anything # about it. So assume it's binary data. elif not content_encoding: content_encoding = 'binary' if compression: body, headers["compression"] = compress(body, compression) return body, content_type, content_encoding