Skip to content

Commit

Permalink
Fix & improve docs about loop provision. Fixes #74. (#75)
Browse files Browse the repository at this point in the history
  • Loading branch information
cjrh authored Aug 6, 2022
1 parent 988a7b5 commit 8e635d1
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
16 changes: 16 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,22 @@ call ``loop.stop()`` inside it: that will initiate shutdown.
a traceback. If you want this behaviour, please see the section on
*error handling* further down.

.. warning::

Note that `aiorun.run(coro)` will create a **new event loop instance**
every time it is invoked (same as `asyncio.run`). This might cause
confusing errors if your code interacts with the default event loop
instance provided by the stdlib `asyncio` library. For such situations
you can provide the actual loop you're using with
`aiorun.run(coro, loop=loop)`. There is more info about this further down.

However, generally speaking, configuring your own loop and providing
it in this way is a code smell. You will find it much easier to
reason about your code if you do all your task creation *inside*
an async context, such as within an `async def` function, because then
there will no ambiguity about which event loop is in play: it will
always be the one returned by `asyncio.get_running_loop()`.


🤔 Why?
----------------
Expand Down
9 changes: 4 additions & 5 deletions aiorun.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,8 @@ def run(
run if missing. The loop will continue to run after the supplied
coroutine finishes. The supplied coroutine is typically
a "main" coroutine from which all other work is spawned.
:param loop: Optionally supply your own loop. If missing, the
default loop attached to the current thread context will
be used, i.e., whatever ``asyncio.get_event_loop()`` returns.
:param loop: Optionally supply your own loop. If missing, a new
event loop instance will be created.
:param shutdown_handler: By default, SIGINT and SIGTERM will be
handled and will stop the loop, thereby invoking the shutdown
sequence. Alternatively you can supply your own shutdown
Expand Down Expand Up @@ -273,8 +272,8 @@ async def new_coro():
# asyncio. So we fall back to KeyboardInterrupt (triggered
# by the user/environment sending CTRL-C, or signal.CTRL_C_EVENT
shutdown_handler(loop)
logger.info("Entering shutdown phase.")

logger.info("Entering shutdown phase.")
if shutdown_callback is not None:
logger.info("Executing provided shutdown_callback.")
try:
Expand Down Expand Up @@ -318,7 +317,7 @@ def sep():
return tasks, do_not_cancel

tasks, do_not_cancel = sep()

async def wait_for_cancelled_tasks():
return await gather(*tasks, *do_not_cancel, return_exceptions=True)

Expand Down

0 comments on commit 8e635d1

Please sign in to comment.