Lab 05: Advanced Async

Objective

Master production-grade asyncio: Semaphore for rate-limiting, TaskGroup for structured concurrency, producer-consumer with asyncio.Queue, retry with exponential backoff, asyncio.timeout (3.11+), async context managers, and building an async pipeline.

Background

asyncio.gather runs tasks concurrently — but without limits, 10,000 simultaneous HTTP requests will crash your process or get you banned. Real async code needs rate-limiting, cancellation, and structured error propagation. Python 3.11's TaskGroup makes this safe by default.

Time

35 minutes

Prerequisites

  • Practitioner Lab 05 (Async/Await)

Tools

  • Docker: zchencow/innozverse-python:latest


Lab Instructions

Step 1: Semaphore — Rate Limiting Concurrent Tasks

💡 asyncio.Semaphore(n) allows at most n coroutines to be inside async with sem: simultaneously. Tasks that exceed the limit are suspended (not cancelled) until a slot opens. This is the async equivalent of a thread pool and is critical for rate-limiting API calls, database connections, and file I/O.

📸 Verified Output:


Step 2: TaskGroup — Structured Concurrency (Python 3.11+)

📸 Verified Output:


Steps 3–8: Producer-Consumer, Retry/Backoff, asyncio.timeout, Async CM, Async Generator, Capstone

📸 Verified Output:


Summary

Pattern
API
Use case

Rate limit

asyncio.Semaphore(n)

Max n concurrent

Structured concurrency

async with TaskGroup()

Group tasks, propagate errors

Worker queue

asyncio.Queue + sentinel

Producer-consumer

Retry backoff

wait_for + sleep

Flaky external services

Hard timeout

asyncio.timeout(secs)

Kill hung operations

Async context manager

__aenter__/__aexit__

Async resource management

Async generator

async def ... yield

Streaming data sources

Further Reading

Last updated