Interview question
Fetch URLs concurrently with a bound, timeout, and structured cleanup
Implements bounded asyncio HTTP concurrency with one client, per-call deadlines, TaskGroup ownership, and deterministic cleanup.
TL;DR
Implements bounded asyncio HTTP concurrency with one client, per-call deadlines, TaskGroup ownership, and deterministic cleanup.
asyncio Semaphore, TaskGroup, timeout ownership, shared client lifetime, result ordering, cancellation, and bounded resource use.
Practice the problem like a real interview: restate, reason, implement, and test.
Implement fetch_all(urls, limit, timeout_seconds) using one httpx.AsyncClient. Run at most limit requests at once, keep results in input order, fail the operation when any request fails, and ensure all sibling tasks and the client are cleaned up. Do not create every connection without a concurrency bound.
urls=[A,B,C], limit=2 -> at most two client.get calls active
B fails -> siblings are cancelled and awaited
results -> returned in A,B,C input order
asyncio.timeout and raise_for_status inside the owned task.import asyncio
import httpx
async def fetch_all(
urls: list[str], limit: int, timeout_seconds: float
) -> list[bytes]:
if limit <= 0:
raise ValueError("limit must be positive")
semaphore = asyncio.Semaphore(limit)
results: list[bytes | None] = [None] * len(urls)
async with httpx.AsyncClient() as client:
async def fetch(index: int, url: str) -> None:
async with semaphore:
async with asyncio.timeout(timeout_seconds):
response = await client.get(url)
response.raise_for_status()
results[index] = response.content
async with asyncio.TaskGroup() as group:
for index, url in enumerate(urls):
group.create_task(fetch(index, url))
return [value for value in results if value is not None]
The work is O(n) requests with O(n) task and result bookkeeping, while active remote calls are bounded by limit.
gather over unbounded coroutines can overwhelm sockets and the dependency.create_task calls can outlive the operation.Move to the linked follow-up, next path step, prerequisite, or deeper variant.
Practice the next layer of the same subject.
Answer a similar question in a different context.