A done set is the set returned by asyncio.wait containing awaitables that have completed, either successfully or with exceptions. The companion pending set contains awaitables still running. section 4.6.1
Use the done set according to how asyncio.wait returns:
- With the default ALL_COMPLETED behavior, every awaitable finishes before return, so the done set contains all tasks and pending is empty. section 4.6.1
- A failed task does not raise at the asyncio.wait call; inspect it by awaiting the task or using task.exception() and task.result(). section 4.6.1
- With FIRST_EXCEPTION, the done set includes the failed task and any tasks already completed, while pending may still contain running tasks. section 4.6.2
- After a timeout, the done set contains tasks completed before the deadline; pending tasks continue running unless explicitly canceled. section 4.6.4
Inspecting completed web requests
Create tasks for concurrent requests, await asyncio.wait, then loop over done. Print task.result() when task.exception() is None; otherwise log the exception. With a one-second timeout, fast requests can be processed while a slower request remains pending. section 4.6.1 section 4.6.4
Listing 4.10 Examining the default behavior of wait
import asyncio
import aiohttp
from aiohttp import ClientSession
from util import async_timed
from chapter_04 import fetch_status
@async_timed()
async def main():
async with aiohttp.ClientSession() as session:
fetchers = \
[asyncio.create_task(fetch_status(session, 'https:/ /example.com')),
asyncio.create_task(fetch_status(session, 'https:/ /example.com'))]
done, pending = await asyncio.wait(fetchers)
print(f'Done task count: {len(done)}')
print(f'Pending task count: {len(pending)}')
for done_task in done:
result = await done_task
print(result)
asyncio.run(main())
Runnable output shows two completed requests and no pending tasks when asyncio.wait uses its default behavior. section 4.6.1
