Adding a GatheringTaskGroup

Currently gathering results from a TaskGroup is quite involved, users must keep track of the submitted tasks and fetch .result() on each one.

async with TaskGroup() as tg:
      r1 = tg.create_task(foo())
      r2 = tg.create_task(bar())
res = [r1.result(), r2.result()]

It would be nice for a new variant in the stdlib with this proposal to my origional question in stack overflow https://stackoverflow.com/questions/75204560/consuming-taskgroup-response

async with GatheringTaskGroup() as tg:
    task1 = tg.create_task(foo())
    task2 = tg.create_task(bar())
print(tg.results())
1 Like

The main barrier I perceive here is that the “cheap happy path” for getting the results of several concurrent tasks is given by `asyncio.gather ` . Every project that will need to keep track of these tasks, act on failure, add more tasks as some are still being resolved, etc… has to come up with more complex patterns.

TaskGroups come with a subset of “tasks that must resolve together, all or nothing, and no one cares about their return value” - if you want anything different, taskgroup is not your “person”. You want the results: in a normal project, just write some logic around “asyncio.wait”.

At some point I did want a taskgroup that would not automatically cancel all sibling tasks on the first error inside one of the tasks - I had to mull out my own. (It is published in the `extraasync` package).

For as much as I like your idea here, I don’t see this kind of change coming to the stdlib. If you want to join in extraasync, drop me a line.

Thanks for you reply!

I thought though the decision to use .gather() and TaskGroups are driven by different considerations than the ease or expectation returning results? The docs also seem to suggest this the preferred model due to the additional guarantees.

No mention was made also that a TaskGroup is unsuited for returning results and .gather should be used instead.

TaskGroup 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.

1 Like

The docs there probably shouldn’t call that a safety guarantee. It’s just a different behavioral choice, and people should pick the one most appropriate for their use case. There are plenty of good reasons not to cancel sibling tasks automatically.

2 Likes