From 6c8e1408fefd1a2c21b2fe0457c74fedb450a92a Mon Sep 17 00:00:00 2001 From: why-not-try-calmer Date: Tue, 25 Oct 2022 15:59:28 +0200 Subject: [PATCH 1/5] Added some clarificatory comments. The purpose of the comments is to rule out the implication that asyncio.TaskGroup is a drop-in replacement / better alternative to asyncio.gather(). Both have their idiomatic uses cases, and asyncio.gather() works well for tasks that do not schedule tasks themselves, especially when the caller needs to consume their result as soon as possible. --- Doc/library/asyncio-task.rst | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index b81d89acf7fd88..931170ec6bcad9 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -256,8 +256,9 @@ Creating Tasks .. note:: - :meth:`asyncio.TaskGroup.create_task` is a newer alternative - that allows for convenient waiting for a group of related tasks. + :meth:`asyncio.TaskGroup.create_task` is a new alternative + based on `structural concurrency principles `_ + that allows for waiting for a group of related tasks with strong safety guarantees. .. important:: @@ -340,7 +341,7 @@ Example:: async with asyncio.TaskGroup() as tg: task1 = tg.create_task(some_coro(...)) task2 = tg.create_task(another_coro(...)) - print("Both tasks have completed now.") + print(f"Both tasks have completed now: {task1.result()}, {task2.result()}") The ``async with`` statement will wait for all tasks in the group to finish. While waiting, new tasks may still be added to the group @@ -459,8 +460,11 @@ Running Tasks Concurrently Tasks/Futures to be cancelled. .. note:: - A more modern way to create and run tasks concurrently and - wait for their completion is :class:`asyncio.TaskGroup`. + A new alternative to create and run tasks concurrently and + wait for their completion is :class:`asyncio.TaskGroup`. While *TaskGroup* + provides strong safety guarantees for scheduling a nesting of subtasks, *gather* comes in handy + for tasks that do not schedule subtasks and need to have their results consumed eagerly + (i.e. when destructuring the result(s) into a tuple). .. _asyncio_example_gather: From a882de799fa397c82320ef27c7f17d56bcd61f6f Mon Sep 17 00:00:00 2001 From: why-not-try-calmer Date: Tue, 25 Oct 2022 22:17:59 +0200 Subject: [PATCH 2/5] Addressing comments and taking onboard suggestions from reviewer. --- Doc/library/asyncio-task.rst | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 931170ec6bcad9..733a40c975e376 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -257,7 +257,7 @@ Creating Tasks .. note:: :meth:`asyncio.TaskGroup.create_task` is a new alternative - based on `structural concurrency principles `_ + based on `structural concurrency principles `_ that allows for waiting for a group of related tasks with strong safety guarantees. .. important:: @@ -461,10 +461,14 @@ Running Tasks Concurrently .. note:: A new alternative to create and run tasks concurrently and - wait for their completion is :class:`asyncio.TaskGroup`. While *TaskGroup* - provides strong safety guarantees for scheduling a nesting of subtasks, *gather* comes in handy - for tasks that do not schedule subtasks and need to have their results consumed eagerly - (i.e. when destructuring the result(s) into a tuple). + wait for their completion is :class:`asyncio.TaskGroup`. *TaskGroup* + provides stronger safety guarantees than *gather* for scheduling a nesting of subtasks. + That is, if a task (or a subtask, a task scheduled by a task) + raises an exception, *TaskGroup* will, while *gather* will not, + cancel the remaining scheduled tasks). However the terser *gather* might be + preferred for *Iterable* of tasks which individually handle their own exceptions, or more + generally, when having some tasks survive the cancellation + of others is an acceptable outcome. .. _asyncio_example_gather: From 1b2172b9f9b0831f7b1fac6b673cb7dcb0c4e301 Mon Sep 17 00:00:00 2001 From: Adrien Date: Thu, 20 Apr 2023 09:17:58 +0200 Subject: [PATCH 3/5] Trimmed down what was superfluous. --- Doc/library/asyncio-task.rst | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 733a40c975e376..2b10794af02be8 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -257,8 +257,8 @@ Creating Tasks .. note:: :meth:`asyncio.TaskGroup.create_task` is a new alternative - based on `structural concurrency principles `_ - that allows for waiting for a group of related tasks with strong safety guarantees. + leveraging structural concurrency; it allows for waiting + for a group of related tasks with strong safety guarantees. .. important:: @@ -465,10 +465,7 @@ Running Tasks Concurrently provides stronger safety guarantees than *gather* for scheduling a nesting of subtasks. That is, if a task (or a subtask, a task scheduled by a task) raises an exception, *TaskGroup* will, while *gather* will not, - cancel the remaining scheduled tasks). However the terser *gather* might be - preferred for *Iterable* of tasks which individually handle their own exceptions, or more - generally, when having some tasks survive the cancellation - of others is an acceptable outcome. + cancel the remaining scheduled tasks). .. _asyncio_example_gather: From 207a8ebcfc9b8477efc0bec9a658861fc11ed13a Mon Sep 17 00:00:00 2001 From: Adrien Date: Thu, 20 Apr 2023 09:28:11 +0200 Subject: [PATCH 4/5] Syntax --- Doc/library/asyncio-task.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 2b10794af02be8..e1add97a9b4d17 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -462,8 +462,8 @@ Running Tasks Concurrently .. note:: A new alternative to create and run tasks concurrently and wait for their completion is :class:`asyncio.TaskGroup`. *TaskGroup* - provides stronger safety guarantees than *gather* for scheduling a nesting of subtasks. - That is, if a task (or a subtask, a task scheduled by a task) + provides stronger safety guarantees than *gather* for scheduling a nesting of subtasks: + if a task (or a subtask, a task scheduled by a task) raises an exception, *TaskGroup* will, while *gather* will not, cancel the remaining scheduled tasks). From c8ae8775b329dcc2e31fdb733807942103678c15 Mon Sep 17 00:00:00 2001 From: Adrien Date: Thu, 20 Apr 2023 09:59:12 +0200 Subject: [PATCH 5/5] Trailing whitespace --- Doc/library/asyncio-task.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index e1add97a9b4d17..ba0f909c405a34 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -257,7 +257,7 @@ Creating Tasks .. note:: :meth:`asyncio.TaskGroup.create_task` is a new alternative - leveraging structural concurrency; it allows for waiting + leveraging structural concurrency; it allows for waiting for a group of related tasks with strong safety guarantees. .. important::