CONCEPT Cited by 1 source
Rust Waker¶
Definition¶
A Waker (std::task::Waker) is the abstract wake-up handle
an async-Rust executor passes into every call to
Future::poll. When a Future
returns Poll::Pending (not ready yet), it stashes a clone of the
Waker with whatever will eventually unblock it — a socket's
readiness notification, a timer, an inner Future — and is
guaranteed to get re-polled only after that thing fires the
Waker.
From the Fly.io 2025-02 incident post:
"The Waker is an abstract handle that allows the Future to instruct the Tokio runtime to call poll, because something has happened."
The Waker is the contract point between userland Futures and the executor: if the Waker is signalled when it shouldn't be, the executor re-polls; if it isn't signalled when it should be, the executor never re-polls.
Two footguns¶
Fly.io's post enumerates them crisply:
- "A
pollof aFuturethat isn'tReadywastes cycles, and, if you have a bug in your code and thatPendingpoll happens to trip aWaker, you'll slip into an infinite loop." — the Future says "not ready, wake me later" and in the same breath wakes itself — cycle. - "An
AsyncReadcanpoll_readto aReadythat doesn't actually progress its underlying state machine." — the Future says "I'm ready!" but polling it again yields the same non-progressing Ready — the caller spins on it.
Both collapse into 100% CPU burn ("samples that almost terminate in libc, but spend next to no time in the kernel doing actual I/O") — canonical spurious-wakeup busy-loop signature.
Why Waker bugs are hard to debug¶
The Waker indirection is the whole point of async Rust —
computations advance only when the executor is told to advance
them. Getting one wrong produces a symptom (busy-polling) that
is structurally different from the bug's location (mis-issued
Waker wake-up at the state-machine boundary). Fly.io's
diagnostic move was a flamegraph: the Future's fully-qualified
type in the flamegraph pointed at the guilty layer
(tokio-rustls::TlsStream).
Seen in¶
- sources/2025-02-26-flyio-taming-a-voracious-rust-proxy —
the rustls TLS state machine mis-handled its Waker on
orderly
close_notifyshutdown with buffered socket data, dragging the containing Future into a busy-poll loop on systems/fly-proxy inIAD. Fixed upstream at rustls PR #1950.
Related¶
- concepts/async-rust-future — what the Waker wakes up.
- concepts/asyncread-contract — the streaming-IO variant.
- concepts/spurious-wakeup-busy-loop — the failure mode.
- systems/tokio — the canonical executor passing Wakers
into
poll. - systems/rustls / systems/tokio-rustls — the library that had the 2025-02 Waker bug.
- companies/flyio