The Event Loop
A track of P33 · Asyncio & Coroutines.
Build the event loop from generators, then drive the real one: async/await, gather and cancellation - and why one cooperative loop outscales a pool of threads for I/O-bound work.
A junior engineer sprinkles async and await across a codebase, sees no
speed-up, and concludes asyncio is snake oil. A senior one knows the loop is a
single cooperative scheduler, spots the one blocking call starving it, and fixes
it in a line. The difference is a mental model — and the fastest way to build it
is to write the event loop yourself.
That is where this track starts. Before any asyncio, you build a round-robin
scheduler over generators: keep a queue of tasks, give each one a single
next() turn, drop the ones that finish. That is an event loop — cooperative
multitasking, where work voluntarily yields control so nothing blocks anything
else. It is the yield→coroutine bridge from P29, made concrete.
Then you meet the real thing on the kernel (real asyncio needs a real Python
loop, which the browser can't provide). asyncio.gather runs many coroutines
concurrently and returns their results in the order you asked; asyncio.wait_for
puts a deadline on one and cancels it cleanly when the time is up. async/await
stop being incantations and become what you already built — suspend points and a
scheduler — which is exactly why one loop can hold ten thousand mostly-waiting
connections that a thread pool never could.