class TornadoConsumer(object): """Non-blocking, Tornado ioloop based consumer""" def __init__(self, broker_url, exchange, exchange_type, queue, routing_key, durable=True, ssl=False, io_loop=None): self.io_loop = io_loop or ioloop.IoLoop.instance() self._conn = None self._callbacks = [] self._broker_url = broker_url self._ssl = ssl self._exchange = Exchange(exchange, exchange_type, durable=durable) self._queue = Queue(queue, exchange=self._exchange, routing_key=routing_key) def add_callback(self, callback): assert not self._conn self._callbacks.append(callback) def start(self): self._conn = Connection(self._broker_url, self._ssl) self._consumer = self._conn.Consumer(self._queue, callbacks=self._callbacks) self.io_loop.add_handler(self._conn.fileno(), self._handle_event) def stop(self): self.io_loop.remove_handler(self._conn.fileno()) self._consumer.close() self._conn.release() def join(self, *args, **kwargs): pass def _handle_event(self): self._conn.drain_nowait()
def test_drain_nowait(self): c = Connection(transport=Mock) c.drain_events = Mock() c.drain_events.side_effect = socket.timeout() c.more_to_read = True self.assertFalse(c.drain_nowait()) self.assertFalse(c.more_to_read) c.drain_events.side_effect = socket.error() c.drain_events.side_effect.errno = errno.EAGAIN c.more_to_read = True self.assertFalse(c.drain_nowait()) self.assertFalse(c.more_to_read) c.drain_events.side_effect = socket.error() c.drain_events.side_effect.errno = errno.EPERM with self.assertRaises(socket.error): c.drain_nowait() c.more_to_read = False c.drain_events = Mock() self.assertTrue(c.drain_nowait()) c.drain_events.assert_called_with(timeout=0) self.assertTrue(c.more_to_read)