From 5ed9c956aaf68a8e2defa9722109aa2c7bcf7ae1 Mon Sep 17 00:00:00 2001 From: pgjones Date: Sat, 23 Jul 2022 11:56:12 +0100 Subject: Add a send_async method to the Signal This allows for signals to send to coroutine receivers by awaiting them. The _async_wrapper and _sync_wrapper allows for conversion of sync and async receivers as required if defined. If not defined a runtime error is raised. The wrappers are used to avoid any direct tie into asyncio, trio, greenbacks, asgiref, or other specific async implementation. --- docs/index.rst | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'docs') diff --git a/docs/index.rst b/docs/index.rst index 9c733bb..c2f111a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -272,6 +272,69 @@ See the documentation of the :obj:`receiver_connected` built-in signal for an example. +Async receivers +--------------- + +Receivers can be coroutine functions which can be called and awaited +via the :meth:`~Signal.send_async` method: + +.. code-block:: python + + sig = blinker.Signal() + + async def receiver(): + ... + + sig.connect(receiver) + await sig.send_async() + +This however requires that all receivers are awaitable which then +precludes the usage of :meth:`~Signal.send`. To mix and match the +:meth:`~Signal.send_async` method takes a ``_sync_wrapper`` argument +such as: + +.. code-block:: python + + sig = blinker.Signal() + + def receiver(): + ... + + sig.connect(receiver) + + def wrapper(func): + + async def inner(*args, **kwargs): + func(*args, **kwargs) + + return inner + + await sig.send_async(_sync_wrapper=wrapper) + +The equivalent usage for :meth:`~Signal.send` is via the +``_async_wrapper`` argument. This usage is will depend on your event +loop, and in the simple case whereby you aren't running within an +event loop the following example can be used: + +.. code-block:: python + + sig = blinker.Signal() + + async def receiver(): + ... + + sig.connect(receiver) + + def wrapper(func): + + def inner(*args, **kwargs): + asyncio.run(func(*args, **kwargs)) + + return inner + + await sig.send(_async_wrapper=wrapper) + + API Documentation ----------------- -- cgit v1.2.1