Module 5 of 9 · Lesson 12 of 26
See how awaited I/O changes scheduling
Work through see how awaited I/O changes scheduling using a runnable reference, a focused regression check and a local extension.
Read in any order. All lessons stay open, including after an unanswered or incorrect check.
Use async def when the called libraries expose awaitable I/O. A blocking database client or time.sleep inside async def still blocks the event-loop thread. An ordinary synchronous FastAPI route can be appropriate for synchronous libraries; changing def to async def without changing the I/O is not an improvement. CPU-heavy password hashing is offloaded in lesson 15. asyncio.gather schedules independent coroutines, but their resources must also be independent. This lesson uses event ordering rather than a wall-clock speed claim because noisy machines make tiny timing benchmarks misleading. The useful question is whether other work can proceed during the wait and whether cancellation and ownership remain clear.
Run lesson12 and read its gate.wait, sleep(0), gate.set and final assertion. The expected sequence is waiting, other-work, resumed. sleep(0) yields control without simulating provider latency. Compare this deterministic order with calling a blocking sleep inside the event-loop thread.
@pytest.mark.asyncio
async def test_lesson12():
events = []
gate = asyncio.Event()
async def waiting():
events.append("waiting")
await gate.wait()
events.append("resumed")
task = asyncio.create_task(waiting())
await asyncio.sleep(0)
events.append("other-work")
gate.set()
await task
assert events == ["waiting", "other-work", "resumed"]
python run_checks.py -k lesson12
Expected result The selected lesson test passes against a new temporary PostgreSQL database; the container is removed afterward.
Keep for reference
Equipment Rental lab and lesson checks
ZIP containing Python source, real Alembic migrations, 26 lesson checks, a dependency lock and text instructions. Extract it before following the local exercise.
Practise locally
Write two coroutines that each announce arrival and wait on the same event. Start both, assert both arrived before releasing the event, then await their results. Add a cancellation case that cancels one waiting task and confirms the other still resumes. Avoid using a fast-machine timing threshold as the only evidence.
The lesson check verifies the reference behavior. Add your own assertions for your change. Local practice is not uploaded or scored by this learning release.
Pause and reflect
What failure does this lesson prevent, and which assertion in lesson12 would expose it?
Use a concrete input, expected result and limitation from your local work. Saving a reflection does not certify the project.
Optional knowledge check
What does await on a genuine I/O operation allow?
Await a synchronous blocking call and it becomes asynchronous.
Try another answer. The library must expose awaitable I/O or be deliberately offloaded.
Other coroutines can run while this operation waits.
Correct. The event loop can schedule other ready work until the awaited operation is ready.
Any blocking call inside async def automatically becomes nonblocking.
Try another answer. Blocking libraries and CPU work still occupy the event-loop thread unless deliberately handled.
This practice does not assess your project or award a certificate.
Your reading progress
Progress is saved in this browser when storage is available.