Asyncio TaskGroup Timeout Gather
Fan out concurrent work with asyncio TaskGroup, wrapping the group in wait_for so one timeout cancels every straggler cleanly.
Code
import asyncio
async def fetch_shard(shard: int) -> list[int]:
await asyncio.sleep(0.2 * shard) # 各分片耗时不一
return [shard * 10, shard * 10 + 1]
async def fetch_slow_shard(shard: int) -> list[int]:
await asyncio.sleep(10)
return []
async def gather_with_timeout(coros, timeout: float) -> list[int]:
async def runner():
results: list[int] = []
async with asyncio.TaskGroup() as tg:
tasks = [tg.create_task(c) for c in coros]
results = [item for task in tasks for item in task.result()]
return results
try:
return await asyncio.wait_for(runner(), timeout=timeout)
except TimeoutError:
print('deadline hit, all pending tasks cancelled')
return []
async def main() -> None:
fast = await gather_with_timeout(
[fetch_shard(i) for i in range(4)], timeout=2.0
)
print('fast path collected:', fast)
interrupted = await gather_with_timeout(
[fetch_shard(1), fetch_slow_shard(9)], timeout=1.0
)
print('timeout path result:', interrupted)
asyncio.run(main())Report a problem with this exampleOpens a pre-filled issue on GitHub.