monty-python icon indicating copy to clipboard operation
monty-python copied to clipboard

Avoid `asyncio.create_task` with no reference

Open CoderJoshDK opened this issue 5 months ago • 0 comments

From the python docs:

[!IMPORTANT] Save a reference to the result of this function, to avoid a task disappearing mid-execution. The event loop only keeps weak references to tasks. A task that isn’t referenced elsewhere may get garbage collected at any time, even before it’s done. For reliable “fire-and-forget” background tasks, gather them in a collection:

This can be solved in one of two ways. Either by explicit strong reference

self.background_task = scheduling.create_task(self.create_socket())

Or by using a TaskGroup. While implementation is situational, create_task should never discard the task.

One solution that exists is to have a list of background tasks. And as part of the add_done_callback, it pops itself. (From docs again)

background_tasks = set()

for i in range(10):
    task = asyncio.create_task(some_coro(param=i))

    # Add task to the set. This creates a strong reference.
    background_tasks.add(task)

    # To prevent keeping references to finished tasks forever,
    # make each task remove its own reference from the set after
    # completion:
    task.add_done_callback(background_tasks.discard)

However, this solution does come with its own set of limitation too.

There are other simplifications that can be made to the scheduler module. But those will be brought up in discord and an issue will be created only if they make sense.

CoderJoshDK avatar Oct 07 '25 11:10 CoderJoshDK