Expand description
Wraps a future with a timeout that also captures a [SpanTrace] of every await point that
was still pending when the deadline fired, by piggy-backing on the Waker contract.
§The technique
Any Future::poll that returns Poll::Pending is required, by the Waker contract, to
arrange for its task to be polled again later – almost always by cloning the Waker it was
given and stashing the clone somewhere (a timer wheel, an I/O reactor’s readiness slot, a
channel’s waiter list, …) so it can be woken once whatever it’s waiting on is ready.
timeout exploits this. Once its deadline elapses, it polls the wrapped future exactly one
more time using a custom Waker (backed by a hand-rolled RawWakerVTable, see
TracingWaker) that captures a [SpanTrace] every time it’s cloned. Each clone marks one
distinct still-pending await point – there can be more than one, e.g. when the future
resolves several sibling branches concurrently. If that final poll is still Pending, every
trace captured during it (for clones that are still alive by the time we look) is returned
via TimeoutElapsed::active_traces.
Because this technique is only ever used for a single, final poll – whatever it returns,
timeout is done, either way (see TracedTimeout::poll) – TracingWaker never
forwards real wake-ups anywhere. There’s no task left that a later wake could usefully
re-poll: by the time any retained clone is woken, timeout’s own future has either already
resolved and been dropped, or is about to resolve on its own regardless.
Structs§
- Timeout
Elapsed - Returned when
innerhasn’t finished withinduration, carrying a [SpanTrace] for every await point ofinnerthat was still pending at that moment. There can be more than one – e.g. when a caller resolves several sibling branches concurrently. - Traced
Timeout - Wraps a future with a timeout that also captures [
SpanTrace]s of whatever was still pending when it fired – seetimeout.
Functions§
- timeout
- Drive
futto completion, limiting its run time toduration. Iffutdoesn’t finish in time, returnsTimeoutElapsedwith a trace of every await point still pending at that moment.