Skip to content

Avoid asyncio.create_task with no reference #658

@CoderJoshDK

Description

@CoderJoshDK

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions