async: add helper to run fire-and-forget tasks

calling asyncio.create_task(...) without storing a reference to the
result can lead to the task being garbage collected before it actually
executed.

https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task

The documentation gives an example of a reliable way to run
fire-and-forget background tasks.

This patch adds an helper to do exactly that.

Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
This commit is contained in:
Olivier Gayot 2023-01-19 12:30:33 +01:00
parent 082e5d9f18
commit b0ced5afb0
1 changed files with 14 additions and 0 deletions

View File

@ -40,6 +40,20 @@ def schedule_task(coro, propagate_errors=True):
return task
# Collection of tasks that we want to fire and forget.
# Keeping a reference to all background tasks ensures that the tasks don't get
# garbage collected before they are done.
# https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task
background_tasks = set()
def run_bg_task(coro, *args, **kwargs) -> None:
""" Run a background task in a fire-and-forget style. """
task = asyncio.create_task(coro, *args, **kwargs)
background_tasks.add(task)
task.add_done_callback(background_tasks.discard)
async def run_in_thread(func, *args):
loop = asyncio.get_running_loop()
try: