From 039a2e99a5f33b70b58e69316b7970d63338df1f Mon Sep 17 00:00:00 2001 From: James McKinney <26463+jpmckinney@users.noreply.github.com> Date: Tue, 18 Jan 2022 15:34:36 -0500 Subject: [PATCH] feat: Add finalback keyword argument to decorate() --- docs/changelog.rst | 8 ++++++++ tests/test_decorators.py | 40 +++++++++++++++++++++++++++++++++++++++- yapw/decorators.py | 4 ++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 6afbef2..0c42a82 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,14 @@ Changelog ========= +0.0.7 (2022-01-18) +------------------ + +Added +~~~~~ + +- :meth:`yapw.decorators.decorate` accepts a ``finalback`` keyword argument. + 0.0.6 (2022-01-17) ------------------ diff --git a/tests/test_decorators.py b/tests/test_decorators.py index c623e21..02af77e 100644 --- a/tests/test_decorators.py +++ b/tests/test_decorators.py @@ -5,13 +5,15 @@ import pytest -from yapw.decorators import default_decode, discard, requeue +from yapw.decorators import decorate, default_decode, discard, requeue # https://pika.readthedocs.io/en/stable/modules/spec.html#pika.spec.Basic.Deliver Deliver = namedtuple("Deliver", "delivery_tag redelivered routing_key") # https://pika.readthedocs.io/en/stable/modules/spec.html#pika.spec.BasicProperties BasicProperties = namedtuple("BasicProperties", "content_type") +logger = logging.getLogger(__name__) + def raises(*args): raise Exception("message") @@ -30,6 +32,16 @@ def closes(*args): opened = False +def finalback(decode, callback, state, channel, method, properties, body): + def errback(): + logger.warning("errback") + + def finalback(): + logger.warning("finalback") + + decorate(decode, callback, state, channel, method, properties, body, errback, finalback) + + @patch("yapw.decorators.nack") def test_decode_json(nack, caplog): caplog.set_level(logging.DEBUG) @@ -139,3 +151,29 @@ def test_finally(nack): global opened assert opened is False + + +@patch("yapw.decorators.nack") +def test_finalback_raises(nack, caplog): + method = Deliver(1, False, "key") + properties = BasicProperties("application/json") + + finalback(default_decode, raises, "state", "channel", method, properties, b'"body"') + + assert len(caplog.records) == 2 + assert caplog.records[0].levelname == "WARNING" + assert caplog.records[0].message == "errback" + assert caplog.records[-1].levelname == "WARNING" + assert caplog.records[-1].message == "finalback" + + +@patch("yapw.decorators.nack") +def test_finalback_passes(nack, caplog): + method = Deliver(1, False, "key") + properties = BasicProperties("application/json") + + finalback(default_decode, passes, "state", "channel", method, properties, b'"body"') + + assert len(caplog.records) == 1 + assert caplog.records[-1].levelname == "WARNING" + assert caplog.records[-1].message == "finalback" diff --git a/yapw/decorators.py b/yapw/decorators.py index 0e5000c..5daf5ae 100644 --- a/yapw/decorators.py +++ b/yapw/decorators.py @@ -66,6 +66,7 @@ def decorate( properties: pika.BasicProperties, body: bytes, errback: Callable[[], None], + finalback: Optional[Callable[[], None]] = None, ) -> None: """ Decode the message ``body`` using the ``decode`` function, and call the consumer ``callback``. @@ -87,6 +88,9 @@ def decorate( callback(state, channel, method, properties, message) except Exception: errback() + finally: + if finalback: + finalback() except Exception: logger.exception("%r can't be decoded, sending SIGUSR2", body) os.kill(os.getpid(), signal.SIGUSR2)