Advanced asyncio: highly concurrent services
You understand asyncio from the inside and write services that handle thousands of connections with structured concurrency, backpressure and graceful shutdown.
Level 401 · 17 lessons · 18 practice labs
Lessons
Inside the event loop
- How the event loop works: the ready queue and the selector
- How coroutines, Futures and Tasks relate
- Structured concurrency: TaskGroup and exception groups
- How cancellation spreads, and shield
- Short task: find lost tasks and silent errors
Streams and protocols
- Backpressure: protecting a slow consumer
- A low-level server with protocols and transports
- Client and server with aiohttp
- Asynchronous database access
- Managing subprocesses with asyncio
- Short task: an asynchronous TCP relay
Resilience and measurement
- Rate limiting with a token bucket
- Graceful shutdown with signals
- asyncio debug mode and slow callbacks
- Testing asynchronous code
- Short task: load test your own service
Capstone
- Capstone: a rate-limited API gateway that shuts down gracefully
Practice labs
- Handing timed reminders to the loop: Schedule reminders with different delays through call_later and show by test that a cancelled one never runs.
- Catching a lost task reference: Keep background tasks that vanish midway for lack of a reference in a set and log their exceptions instead of swallowing them.
- Wrapping a callback library with a Future: Turn an old library that delivers results by callback into an awaitable interface that safely hands results from another thread to the loop.
- Cleaning up a temp file on cancellation: Add finally-based cleanup to a download task that leaves its temp file behind when cancelled and show it does not swallow CancelledError.
- Splitting an exception group by type: Split the exception group from a TaskGroup into network and validation errors with except*, count each type and re-raise the unexpected.
- Shielding a critical write from cancellation: Protect a two-step save that timeouts leave half done with shield and prove by test that it is written fully or not at all even on cancellation.
- A line echo server with streams: Write a server with asyncio.start_server that echoes line by line and closes the connection cleanly on an empty line.
- Protecting memory against a slow reader: Add drain and a write buffer limit to a server whose memory balloons when feeding a slow client and measure the peak memory use.
- Length-prefixed frames with a Protocol class: Write a low-level Protocol class that assembles length-prefixed frames from data arriving in pieces and drops the connection on an oversized frame.
- Fetching lab page statuses concurrently: Collect the status codes of an address list on the lab target concurrently through one aiohttp session and mark timeouts separately.
- Ending a hung subprocess: Put a timeout on a command run through asyncio, terminate the process when it expires, leave no zombie and return the partial output.
- Curing connection pool starvation: Find the pool exhaustion in an async data access layer that holds connections too long, narrow the scope and show waits disappear under the load test.
- Writing the first test for an async function: Write tests for an async price aggregator that run without real waiting, using a fake clock and a fake service.
- Limiting requests with a token bucket: Write an async token bucket that limits requests per second and burst size and show by measurement that the limit is never exceeded.
- Finishing open work and exiting on SIGTERM: Add a shutdown flow to a service that stops accepting work on the signal, gives open jobs a grace period and cancels the rest when it runs out.
- Collecting subprocess output asynchronously: Run three commands concurrently with asyncio.create_subprocess_exec and collect each one's output and return code, without using a shell.
- Testing a timeout without waiting: Test a client with a thirty-second timeout by replacing the slow service with a fake and shrinking the duration, so the test finishes in under a second and confirms the fallback value is returned.
- A test that catches a race every time: Reproduce on every run a flaky bug where two tasks update the same balance by steering task order with Event objects, then fix it with a lock.
About this course
You understand asyncio from the inside and write services that handle thousands of connections with structured concurrency, backpressure and graceful shutdown.
What you will learn
- Inside the event loop
- Streams and protocols
- Resilience and measurement
- Capstone
Prerequisites
You should have practised the topics of the same path up to level 301.
Lab environment
Lessons run in your own Kali Linux terminal in the browser, connected to a private lab network. Nothing to install.
Frequently asked questions
- Is this course right for my level?
- The course is at level 401; it assumes you know the topics of the lower-level courses.
- Is there anything to install?
- No. Every lesson runs in your own lab environment that opens in the browser.
- How do lessons work?
- Each lesson has 8 to 10 steps and a short quiz. Early steps show the command to type, later steps give less help; if two attempts fail, the solution opens.
- Can I try it for free?
- Yes. The first three lessons of every course are free.