From a1b586d9b9b2bc56c032c5bdc0b3d7b9d771c890 Mon Sep 17 00:00:00 2001 From: Andreas Grommek <76997441+agrommek@users.noreply.github.com> Date: Thu, 26 May 2022 15:23:23 +0200 Subject: [PATCH 1/4] added explicit information about weak and strong references --- Doc/library/asyncio-task.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 8e3d49dcf9d717..ffb585b9012133 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -226,7 +226,9 @@ Creating Tasks .. important:: Save a reference to the result of this function, to avoid - a task disappearing mid execution. + a task disappearing mid execution. The event loop only keeps + weak references to all task. Without a strong reference, the + task may get garbage-collected at any time. .. versionadded:: 3.7 From 5148c7712904356d5a898940d6c3f677950513d5 Mon Sep 17 00:00:00 2001 From: Andreas Grommek <76997441+agrommek@users.noreply.github.com> Date: Thu, 26 May 2022 15:48:24 +0200 Subject: [PATCH 2/4] added code example to keep strong references around --- Doc/library/asyncio-task.rst | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index ffb585b9012133..a828e17e5b8857 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -228,7 +228,23 @@ Creating Tasks Save a reference to the result of this function, to avoid a task disappearing mid execution. The event loop only keeps weak references to all task. Without a strong reference, the - task may get garbage-collected at any time. + task may get garbage-collected at any time. If you want to have + "fire-and-forget" background tasks you can do something like this:: + + # create an empty set to store references to background tasks + background_tasks = set() + + # start 10 background tasks + for i in range(10): + task = asyncio.create_task(some_coro(param=i)) + + # Add task to set. This creates a strong reference. + background_tasks.add(task) + + # To prevent accumulation of references to already finished + # tasks, make each task remove its own reference from set after + # completion: + task.add_done_callback(lambda t: background_tasks.discard(t)) .. versionadded:: 3.7 From e7bf6f8fca24c8b1e171167eeac3060fe3d37b24 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Thu, 26 May 2022 14:51:26 +0000 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Documentation/2022-05-26-14-51-25.gh-issue-88831.5Cccr5.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Documentation/2022-05-26-14-51-25.gh-issue-88831.5Cccr5.rst diff --git a/Misc/NEWS.d/next/Documentation/2022-05-26-14-51-25.gh-issue-88831.5Cccr5.rst b/Misc/NEWS.d/next/Documentation/2022-05-26-14-51-25.gh-issue-88831.5Cccr5.rst new file mode 100644 index 00000000000000..983bea981a9b20 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-05-26-14-51-25.gh-issue-88831.5Cccr5.rst @@ -0,0 +1 @@ +Augmented documentation of asyncio.create_task(). Clarified the need to keep strong references to tasks and added a code snippet detailing how to to this. From 98fd62f05caa7ddac90763e7ff403ed3cc8830f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Tue, 7 Jun 2022 10:38:52 +0200 Subject: [PATCH 4/4] Reword the message, remove spurious lambda --- Doc/library/asyncio-task.rst | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index a828e17e5b8857..7796e47d4674dc 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -227,24 +227,23 @@ Creating Tasks Save a reference to the result of this function, to avoid a task disappearing mid execution. The event loop only keeps - weak references to all task. Without a strong reference, the - task may get garbage-collected at any time. If you want to have - "fire-and-forget" background tasks you can do something like this:: + 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:: - # create an empty set to store references to background tasks background_tasks = set() - # start 10 background tasks for i in range(10): task = asyncio.create_task(some_coro(param=i)) - # Add task to set. This creates a strong reference. + # Add task to the set. This creates a strong reference. background_tasks.add(task) - # To prevent accumulation of references to already finished - # tasks, make each task remove its own reference from set after + # To prevent keeping references to finished tasks forever, + # make each task remove its own reference from the set after # completion: - task.add_done_callback(lambda t: background_tasks.discard(t)) + task.add_done_callback(background_tasks.discard) .. versionadded:: 3.7