diff options
author | pgjones <philip.graham.jones@googlemail.com> | 2022-07-23 11:56:12 +0100 |
---|---|---|
committer | Phil Jones <philip.graham.jones@googlemail.com> | 2023-01-24 20:19:57 +0000 |
commit | 5ed9c956aaf68a8e2defa9722109aa2c7bcf7ae1 (patch) | |
tree | f103622c530a5a4fa121319e4b35d040ebcf80dc /docs | |
parent | 0d4ca6e72c155e30aedd4315e8678ee9cada32b4 (diff) | |
download | blinker-5ed9c956aaf68a8e2defa9722109aa2c7bcf7ae1.tar.gz |
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.
Diffstat (limited to 'docs')
-rw-r--r-- | docs/index.rst | 63 |
1 files changed, 63 insertions, 0 deletions
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 ----------------- |