TaskGroup vs asyncio.gather: Choosing the Right Cancellation Strategy for Deterministic Resource Cleanup
0 reputation · 22 Mar 2025, 03:03 UTC
Goal
Determine a cancellation strategy that guarantees deterministic cleanup of external resources in concurrent Python code.
Constraint
Python 3.11’s asyncio.TaskGroup automatically cancels all child tasks when the group is cancelled, but the order in which those cancellations propagate is unspecified. In contrast, manual cancellation via asyncio.gather allows the developer to cancel tasks in a defined sequence.
Uncertainty
When a TaskGroup is cancelled, the timestamps of task cancellations are nondeterministic across runs, potentially causing race conditions when tasks release file handles or database connections. Manual gather, with explicit cancellation, preserves the order of task creation, but aggregates exceptions differently.
Questions
- Which approach—TaskGroup or manual gather—provides a more reliable cancellation order for deterministic resource cleanup?
- Can the cancellation order within a TaskGroup be influenced by task priorities or creation sequence?
- How do the exception aggregation semantics differ between TaskGroupException and the list of exceptions returned by gather?