Пример #1
0
    def __init__(
            self,
            parameters,
            schema=None,
            on_error='requeue_once',
            prefetch_count=None,
            requeue_delay=None,
            requeue_max_count=None,
            **kwargs
    ):

        logger.debug("construct new _AMQPProtocol (id = %r)...", id(self))
        TwistedProtocolConnection.__init__(
            self, _ConnectionParameters(**parameters))

        self.virtual_host = parameters.get('virtual_host') or ""
        self.clock = reactor
        self.schema = schema
        self.prefetch_count = prefetch_count

        assert not on_error or on_error in self.ON_ERROR_STRATEGIES
        self.on_error = on_error or 'requeue'
        self.requeue_max_count = requeue_max_count if requeue_max_count is not None else 50000
        self.requeue_delay = requeue_delay if requeue_delay is not None else 120

        # -- state
        self._published_messages = {}
        self._consumer_state = {}
        self._delayed_requeue_tasks = {}
        self._ready_for_publish = False
Пример #2
0
 def __init__(self, parameters, confirms=True):
     TwistedProtocolConnection.__init__(self, parameters)
     self._confirms = confirms
     self._channel = None
     self._publish_channel = None
     # Map queue names to fedora_messaging.twisted.consumer.Consumer objects
     self._consumers = {}
     self.factory = None
Пример #3
0
 def __init__(self, parameters, confirms=True):
     TwistedProtocolConnection.__init__(self, parameters)
     if confirms and _pika_version < pkg_resources.parse_version("1.0.0b1"):
         _std_log.error("Message confirmation is only available with pika 1.0.0+")
         confirms = False
     self._confirms = confirms
     self._channel = None
     # Map queue names to fedora_messaging.twisted.consumer.Consumer objects
     self._consumers = {}
     self.factory = None
Пример #4
0
 def __init__(self, parameters, confirms=True):
     TwistedProtocolConnection.__init__(self, parameters)
     self._parameters = parameters
     if confirms and _pika_version < pkg_resources.parse_version("1.0.0b1"):
         _log.error(
             "Message confirmation is only available with pika 1.0.0+")
         confirms = False
     self._confirms = confirms
     self._channel = None
     self._running = False
     # Map queue names to dictionaries representing consumers
     self._consumers = {}
     self.factory = None
Пример #5
0
 def connectionReady(self, res=None):
     """Called when the AMQP connection is ready.
     """
     # The optional `res` argument is for compatibility with pika < 1.0.0
     # Create channel
     self._channel = yield self.channel()
     log.msg("AMQP channel created", system=self.name,
             logLevel=logging.DEBUG)
     yield self._channel.basic_qos(
         prefetch_count=config.conf["qos"]["prefetch_count"],
         prefetch_size=config.conf["qos"]["prefetch_size"],
     )
     if self._confirms:
         yield self._channel.confirm_delivery()
     if _pika_version < pkg_resources.parse_version("1.0.0b1"):
         TwistedProtocolConnection.connectionReady(self, res)
Пример #6
0
    def connectionReady(self, res=None):
        """
        Callback invoked when the AMQP connection is ready.

        This API is not meant for users.
        """
        # The optional `res` argument is for compatibility with pika < 1.0.0
        # Create channel
        self._channel = yield self._allocate_channel()
        yield self._channel.basic_qos(
            prefetch_count=config.conf["qos"]["prefetch_count"],
            prefetch_size=config.conf["qos"]["prefetch_size"],
            all_channels=True,
        )
        if _pika_version < pkg_resources.parse_version("1.0.0b1"):
            TwistedProtocolConnection.connectionReady(self, res)
Пример #7
0
    def connectionLost(self, reason):

        logger.debug("connection lost due to %r", reason)
        self._ready_for_publish = None

        cstates = list(self._consumer_state.items())
        self._consumer_state.clear()

        for ct, cstate in cstates:
            queue_obj = cstate['queue_obj']
            no_ack = cstate['no_ack']
            if no_ack and not queue_obj.closed:
                logger.debug("put None to pika queue %r", queue_obj)
                queue_obj.put(None)
            elif not queue_obj.closed and not no_ack:
                logger.debug("close pika queue %r", queue_obj)
                queue_obj.close(reason)

        self._fail_published_messages(reason)
        TwistedProtocolConnection.connectionLost(self, reason)
Пример #8
0
    def __init__(self, parameters, confirms=True):
        """Initialize the protocol.

        Args:
            parameters (pika.ConnectionParameters): The connection parameters.
            confirms (bool): If True, all outgoing messages will require a
                confirmation from the server, and the Deferred returned from
                the publish call will wait for that confirmation.
        """
        TwistedProtocolConnection.__init__(self, parameters)
        self._parameters = parameters
        if confirms and _pika_version < pkg_resources.parse_version("1.0.0b1"):
            log.msg("Message confirmation is only available with pika 1.0.0+",
                    system=self.name, logLevel=logging.ERROR)
            confirms = False
        self._confirms = confirms
        self._channel = None
        self._running = False
        self._queues = set()
        self._message_callback = None
        self.factory = None
Пример #9
0
    def connectionReady(self, res=None):
        """
        Callback invoked when the AMQP connection is ready (when self.ready fires).

        This API is not meant for users.

        Args:
            res: This is an unused argument that provides compatibility with Pika
                versions lower than 1.0.0.
        """
        self._channel = yield self._allocate_channel()
        if _pika_version < pkg_resources.parse_version("1.0.0b1"):
            extra_args = dict(all_channels=True)
        else:
            extra_args = dict(global_qos=True)
        yield self._channel.basic_qos(
            prefetch_count=config.conf["qos"]["prefetch_count"],
            prefetch_size=config.conf["qos"]["prefetch_size"],
            **extra_args
        )
        if _pika_version < pkg_resources.parse_version("1.0.0b1"):
            TwistedProtocolConnection.connectionReady(self, res)
Пример #10
0
 def setUp(self):
     self.conn = TwistedProtocolConnection()
     self.conn._impl = mock.Mock()
Пример #11
0
class TwistedProtocolConnectionTestCase(TestCase):
    def setUp(self):
        self.conn = TwistedProtocolConnection()
        self.conn._impl = mock.Mock()

    @deferred(timeout=5.0)
    def test_connection(self):
        # Verify that the connection opening is properly wrapped.
        transport = mock.Mock()
        self.conn.connectionMade = mock.Mock()
        self.conn.makeConnection(transport)
        self.conn._impl.connection_made.assert_called_once_with(transport)
        self.conn.connectionMade.assert_called_once()
        d = self.conn.ready
        self.conn._on_connection_ready(None)
        return d

    @deferred(timeout=5.0)
    def test_channel(self):
        # Verify that the request for a channel works properly.
        channel = mock.Mock()
        self.conn._impl.channel.side_effect = lambda n, cb: cb(channel)
        d = self.conn.channel()
        self.conn._impl.channel.assert_called_once()

        def check(result):
            self.assertTrue(isinstance(result, TwistedChannel))

        d.addCallback(check)
        return d

    @deferred(timeout=5.0)
    def test_channel_errback_if_connection_closed(self):
        # Verify calls to channel() that haven't had their callback invoked
        # errback when the connection closes.
        self.conn._on_connection_ready("dummy")

        d = self.conn.channel()

        self.conn._on_connection_closed("test conn", RuntimeError("testing"))

        self.assertEqual(len(self.conn._calls), 0)
        return self.assertFailure(d, RuntimeError)

    def test_dataReceived(self):
        # Verify that the data is transmitted to the callback method.
        self.conn.dataReceived("testdata")
        self.conn._impl.data_received.assert_called_once_with("testdata")

    @deferred(timeout=5.0)
    def test_connectionLost(self):
        # Verify that the "ready" Deferred errbacks on connectionLost, and that
        # the underlying implementation callback is called.
        ready_d = self.conn.ready
        error = RuntimeError("testreason")
        self.conn.connectionLost(error)
        self.conn._impl.connection_lost.assert_called_with(error)
        self.assertIsNone(self.conn.ready)
        return self.assertFailure(ready_d, RuntimeError)

    def test_connectionLost_twice(self):
        # Verify that calling connectionLost twice will not cause an
        # AlreadyCalled error on the Deferred.
        ready_d = self.conn.ready
        error = RuntimeError("testreason")
        self.conn.connectionLost(error)
        self.assertTrue(ready_d.called)
        ready_d.addErrback(lambda f: None)  # silence the error
        self.assertIsNone(self.conn.ready)
        # A second call must not raise AlreadyCalled
        self.conn.connectionLost(error)

    @deferred(timeout=5.0)
    def test_on_connection_ready(self):
        # Verify that the "ready" Deferred is resolved on _on_connection_ready.
        d = self.conn.ready
        self.conn._on_connection_ready("testresult")
        self.assertTrue(d.called)
        d.addCallback(self.assertIsNone)
        return d

    def test_on_connection_ready_twice(self):
        # Verify that calling _on_connection_ready twice will not cause an
        # AlreadyCalled error on the Deferred.
        d = self.conn.ready
        self.conn._on_connection_ready("testresult")
        self.assertTrue(d.called)
        # A second call must not raise AlreadyCalled
        self.conn._on_connection_ready("testresult")

    @deferred(timeout=5.0)
    def test_on_connection_ready_method(self):
        # Verify that the connectionReady method is called when the "ready"
        # Deferred is resolved.
        d = self.conn.ready
        self.conn.connectionReady = mock.Mock()
        self.conn._on_connection_ready("testresult")
        self.conn.connectionReady.assert_called_once()
        return d

    @deferred(timeout=5.0)
    def test_on_connection_failed(self):
        # Verify that the "ready" Deferred errbacks on _on_connection_failed.
        d = self.conn.ready
        self.conn._on_connection_failed(None)
        return self.assertFailure(d, AMQPConnectionError)

    def test_on_connection_failed_twice(self):
        # Verify that calling _on_connection_failed twice will not cause an
        # AlreadyCalled error on the Deferred.
        d = self.conn.ready
        self.conn._on_connection_failed(None)
        self.assertTrue(d.called)
        d.addErrback(lambda f: None)  # silence the error
        # A second call must not raise AlreadyCalled
        self.conn._on_connection_failed(None)

    @deferred(timeout=5.0)
    def test_on_connection_closed(self):
        # Verify that the "closed" Deferred is resolved on
        # _on_connection_closed.
        self.conn._on_connection_ready("dummy")
        d = self.conn.closed
        self.conn._on_connection_closed("test conn", "test reason")
        self.assertTrue(d.called)
        d.addCallback(self.assertEqual, "test reason")
        return d

    def test_on_connection_closed_twice(self):
        # Verify that calling _on_connection_closed twice will not cause an
        # AlreadyCalled error on the Deferred.
        self.conn._on_connection_ready("dummy")
        d = self.conn.closed
        self.conn._on_connection_closed("test conn", "test reason")
        self.assertTrue(d.called)
        # A second call must not raise AlreadyCalled
        self.conn._on_connection_closed("test conn", "test reason")

    @deferred(timeout=5.0)
    def test_on_connection_closed_Failure(self):
        # Verify that the _on_connection_closed method can be called with
        # a Failure instance without triggering the errback path.
        self.conn._on_connection_ready("dummy")
        error = RuntimeError()
        d = self.conn.closed
        self.conn._on_connection_closed("test conn", Failure(error))
        self.assertTrue(d.called)

        def _check_cb(result):
            self.assertEqual(result, error)

        def _check_eb(_failure):
            self.fail("The errback path should not have been triggered")

        d.addCallbacks(_check_cb, _check_eb)
        return d

    def test_close(self):
        # Verify that the close method is properly wrapped.
        self.conn._impl.is_closed = False
        self.conn.closed = "TESTING"
        value = self.conn.close()
        self.assertEqual(value, "TESTING")
        self.conn._impl.close.assert_called_once_with(200, "Normal shutdown")

    def test_close_twice(self):
        # Verify that the close method is only transmitted when open.
        self.conn._impl.is_closed = True
        self.conn.close()
        self.conn._impl.close.assert_not_called()
Пример #12
0
 def setUp(self):
     self.conn = TwistedProtocolConnection()
     self.conn._impl = mock.Mock()
Пример #13
0
class TwistedProtocolConnectionTestCase(TestCase):

    def setUp(self):
        self.conn = TwistedProtocolConnection()
        self.conn._impl = mock.Mock()

    @deferred(timeout=5.0)
    def test_connection(self):
        # Verify that the connection opening is properly wrapped.
        transport = mock.Mock()
        self.conn.connectionMade = mock.Mock()
        self.conn.makeConnection(transport)
        self.conn._impl.connection_made.assert_called_once_with(
            transport)
        self.conn.connectionMade.assert_called_once()
        d = self.conn.ready
        self.conn._on_connection_ready(None)
        return d

    @deferred(timeout=5.0)
    def test_channel(self):
        # Verify that the request for a channel works properly.
        channel = mock.Mock()
        self.conn._impl.channel.side_effect = lambda n, cb: cb(channel)
        d = self.conn.channel()
        self.conn._impl.channel.assert_called_once()

        def check(result):
            self.assertTrue(isinstance(result, TwistedChannel))
        d.addCallback(check)
        return d

    def test_dataReceived(self):
        # Verify that the data is transmitted to the callback method.
        self.conn.dataReceived("testdata")
        self.conn._impl.data_received.assert_called_once_with("testdata")

    @deferred(timeout=5.0)
    def test_connectionLost(self):
        # Verify that the "ready" Deferred errbacks on connectionLost, and that
        # the underlying implementation callback is called.
        ready_d = self.conn.ready
        error = RuntimeError("testreason")
        self.conn.connectionLost(error)
        self.conn._impl.connection_lost.assert_called_with(error)
        self.assertIsNone(self.conn.ready)
        return self.assertFailure(ready_d, RuntimeError)

    def test_connectionLost_twice(self):
        # Verify that calling connectionLost twice will not cause an
        # AlreadyCalled error on the Deferred.
        ready_d = self.conn.ready
        error = RuntimeError("testreason")
        self.conn.connectionLost(error)
        self.assertTrue(ready_d.called)
        ready_d.addErrback(lambda f: None)  # silence the error
        self.assertIsNone(self.conn.ready)
        # A second call must not raise AlreadyCalled
        self.conn.connectionLost(error)

    @deferred(timeout=5.0)
    def test_on_connection_ready(self):
        # Verify that the "ready" Deferred is resolved on _on_connection_ready.
        d = self.conn.ready
        self.conn._on_connection_ready("testresult")
        self.assertTrue(d.called)
        d.addCallback(self.assertIsNone)
        return d

    def test_on_connection_ready_twice(self):
        # Verify that calling _on_connection_ready twice will not cause an
        # AlreadyCalled error on the Deferred.
        d = self.conn.ready
        self.conn._on_connection_ready("testresult")
        self.assertTrue(d.called)
        # A second call must not raise AlreadyCalled
        self.conn._on_connection_ready("testresult")

    @deferred(timeout=5.0)
    def test_on_connection_ready_method(self):
        # Verify that the connectionReady method is called when the "ready"
        # Deferred is resolved.
        d = self.conn.ready
        self.conn.connectionReady = mock.Mock()
        self.conn._on_connection_ready("testresult")
        self.conn.connectionReady.assert_called_once()
        return d

    @deferred(timeout=5.0)
    def test_on_connection_failed(self):
        # Verify that the "ready" Deferred errbacks on _on_connection_failed.
        d = self.conn.ready
        self.conn._on_connection_failed(None)
        return self.assertFailure(d, AMQPConnectionError)

    def test_on_connection_failed_twice(self):
        # Verify that calling _on_connection_failed twice will not cause an
        # AlreadyCalled error on the Deferred.
        d = self.conn.ready
        self.conn._on_connection_failed(None)
        self.assertTrue(d.called)
        d.addErrback(lambda f: None)  # silence the error
        # A second call must not raise AlreadyCalled
        self.conn._on_connection_failed(None)

    @deferred(timeout=5.0)
    def test_on_connection_closed(self):
        # Verify that the "closed" Deferred is resolved on
        # _on_connection_closed.
        self.conn._on_connection_ready("dummy")
        d = self.conn.closed
        self.conn._on_connection_closed("test conn", "test reason")
        self.assertTrue(d.called)
        d.addCallback(self.assertEqual, "test reason")
        return d

    def test_on_connection_closed_twice(self):
        # Verify that calling _on_connection_closed twice will not cause an
        # AlreadyCalled error on the Deferred.
        self.conn._on_connection_ready("dummy")
        d = self.conn.closed
        self.conn._on_connection_closed("test conn", "test reason")
        self.assertTrue(d.called)
        # A second call must not raise AlreadyCalled
        self.conn._on_connection_closed("test conn", "test reason")

    @deferred(timeout=5.0)
    def test_on_connection_closed_Failure(self):
        # Verify that the _on_connection_closed method can be called with
        # a Failure instance without triggering the errback path.
        self.conn._on_connection_ready("dummy")
        error = RuntimeError()
        d = self.conn.closed
        self.conn._on_connection_closed("test conn", Failure(error))
        self.assertTrue(d.called)

        def _check_cb(result):
            self.assertEqual(result, error)

        def _check_eb(_failure):
            self.fail("The errback path should not have been triggered")

        d.addCallbacks(_check_cb, _check_eb)
        return d

    def test_close(self):
        # Verify that the close method is properly wrapped.
        self.conn._impl.is_closed = False
        self.conn.closed = "TESTING"
        value = self.conn.close()
        self.assertEqual(value, "TESTING")
        self.conn._impl.close.assert_called_once_with(200, "Normal shutdown")

    def test_close_twice(self):
        # Verify that the close method is only transmitted when open.
        self.conn._impl.is_closed = True
        self.conn.close()
        self.conn._impl.close.assert_not_called()
Пример #14
0
 def connectionMade(self):
     logger.debug("amqp connection was made")
     TwistedProtocolConnection.connectionMade(self)
     self.ready.addCallback(lambda _: self.handshakingMade())
     self.ready.addErrback(self.handshakingFailed)
 def buildProtocol(self, addr):
     parameters = pika.ConnectionParameters()
     protocol = TwistedProtocolConnection(parameters)
     protocol.add_on_open_callback(on_connect)
     return protocol