AI Engineer Portal
Your personal operating system for career transition.
Private mode
Exercise
Async provider client with semaphore rate limiting
Async provider client with semaphore rate limiting
Running LLM calls serially on a batch is 10–50x slower than running them concurrently. But unlimited concurrency hammers rate limits. A semaphore is the standard tool for bounded concurrency.
What you are building
Implement an AsyncBatchProcessor class that:
- Accepts a
process_fn: Callable[[str], Awaitable[str]]— the async function to call for each item (simulates an LLM API call) - Accepts
max_concurrent: int = 5— maximum simultaneous calls async def run(self, items: list[str]) -> tuple[list[str], list[dict]]— processes all items concurrently within the semaphore limit. Returns(results, failures)wherefailuresis a list of{"index": i, "error": str}dicts.
Requirements
- Use
asyncio.Semaphore(max_concurrent)to bound concurrency - Use
asyncio.gather(..., return_exceptions=True)to collect results - A failed item should not abort other items
- Results list must have the same length as
items, withNonefor failed items - Failures list must contain the index and error string for each failed item
Example
import asyncio
async def fake_llm(text: str) -> str:
await asyncio.sleep(0.01)
if text == "fail":
raise ValueError("Simulated failure")
return f"processed: {text}"
processor = AsyncBatchProcessor(process_fn=fake_llm, max_concurrent=3)
results, failures = asyncio.run(processor.run(["a", "b", "fail", "d"]))
# results == ["processed: a", "processed: b", None, "processed: d"]
# failures == [{"index": 2, "error": "Simulated failure"}]
Api Async / medium / Step 20 of 23
Practice stage
Async and provider control
Hint
Make waiting behavior explicit. Timeouts, retries, and concurrency limits matter more than squeezing everything into one helper.
Success criteria
- - Uses async boundaries coherently
- - Makes timeout and retry decisions legible
- - Would be maintainable under provider instability
Review checklist
- - Is timeout behavior explicit?
- - Is retryable failure separate from terminal failure?
- - Would logs reveal what actually timed out?
Related lessons
Practice
Generate a variation
Generate a new exercise variation to deepen understanding or practice a related concept.
Attempt history
Recent submissions
Before you submit, decide what a strong answer should make obvious to the reviewer.
No attempts yet.