Skip to content

Commit cb70222

Browse files
itamarojbower-fb
authored andcommitted
pythongh-104144: Optimize gather to finish eagerly when all futures complete eagerly (python#104138)
1 parent b4f3496 commit cb70222

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

Lib/asyncio/tasks.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,7 @@ def _done_callback(fut):
813813
children = []
814814
nfuts = 0
815815
nfinished = 0
816+
done_futs = []
816817
loop = None
817818
outer = None # bpo-46672
818819
for arg in coros_or_futures:
@@ -829,7 +830,10 @@ def _done_callback(fut):
829830

830831
nfuts += 1
831832
arg_to_fut[arg] = fut
832-
fut.add_done_callback(_done_callback)
833+
if fut.done():
834+
done_futs.append(fut)
835+
else:
836+
fut.add_done_callback(_done_callback)
833837

834838
else:
835839
# There's a duplicate Future object in coros_or_futures.
@@ -838,6 +842,13 @@ def _done_callback(fut):
838842
children.append(fut)
839843

840844
outer = _GatheringFuture(children, loop=loop)
845+
# Run done callbacks after GatheringFuture created so any post-processing
846+
# can be performed at this point
847+
# optimization: in the special case that *all* futures finished eagerly,
848+
# this will effectively complete the gather eagerly, with the last
849+
# callback setting the result (or exception) on outer before returning it
850+
for fut in done_futs:
851+
_done_callback(fut)
841852
return outer
842853

843854

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Optimize :func:`asyncio.gather` when using :func:`asyncio.eager_task_factory`
2+
to complete eagerly if all fututres completed eagerly.
3+
Avoid scheduling done callbacks for futures that complete eagerly.

0 commit comments

Comments
 (0)