Skip to content
This repository has been archived by the owner on Mar 6, 2024. It is now read-only.

asyncio.run: close loops if we created them #79

Closed
wants to merge 2 commits into from

Conversation

minrk
Copy link

@minrk minrk commented May 5, 2023

rather than leaving an open event loop, clean it up when we are done with it.

more closely matches asyncio.run behavior when run from outside an event loop.

This could be considered a breaking change, in that asyncio.run no longer re-uses an event loop when called from outside asyncio, but I hope nobody is relying on creating something in one asyncio.run call and using it in another, since that's exactly what asyncio.run is meant to prevent.

An example script:

import asyncio

# import nest_asyncio
# nest_asyncio.apply()

async def sleep_awhile():
    await asyncio.sleep(5)

async def show_tasks(step):
    asyncio.create_task(sleep_awhile(), name=f"sleep_while {step}")
    for task in asyncio.all_tasks():
        if task is not asyncio.current_task():
            print(task)

if __name__ == "__main__":
    for i in range(5):
        print(f"step {i}")
        asyncio.run(show_tasks(i))
  • With unpatched asyncio.run, tasks created during the run call are cleaned up between asyncio.run calls.
  • With nest_asyncio (without this patch), tasks created from one asyncio.run are still running, and accumulate from one run call to the next
  • With this patch, nest_asyncio restores the behavior of asyncio.run when run outside an already running asyncio loop

Behavior should be unchanged for reentrant calls to asyncio.run, but arguably something like a TaskGroup (or simpler: a check of all_tasks) could be used to cleanup any tasks created during a nested call to asyncio.run as well.

xref minrk/asyncio-atexit#3 cc @jacobtomlinson

rather than leaving an open event loop, clean it up when we are done with it

more closely matches asyncio.run behavior when run from outside an event loop
@erdewit
Copy link
Owner

erdewit commented May 5, 2023

Thank you for this very thoughtful PR. Unfortunately I have to decline it, since it is a breaking change that will for certain cause problems in a lot of cases where nest_asyncio is used. In practice there is indeed a reliance on one event loop that runs all tasks.

I appreciate you wanting to fix a bug in your project, but I have to be very conservative with changes to nest_asyncio since it is used so much and in such diverse situations.

@erdewit erdewit closed this May 5, 2023
@minrk minrk deleted the run-close branch May 5, 2023 12:02
@minrk
Copy link
Author

minrk commented May 5, 2023

No worries, I certainly appreciate being conservative about potential breaking changes. I thought maybe nest_asyncio aimed to match standard asyncio behavior, except when run from within a running loop.

I appreciate you wanting to fix a bug in your project

To be clear, this isn't a bug in my project, even though it was reported on my package, but turned out to be nest_asyncio not meeting users' expectations of asyncio.run. But I know there's always someone who relies on a bug, so I understand.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants