Skip to main content

Module timeout_trace

Module timeout_trace 

Source
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§

TimeoutElapsed
Returned when inner hasn’t finished within duration, carrying a [SpanTrace] for every await point of inner that was still pending at that moment. There can be more than one – e.g. when a caller resolves several sibling branches concurrently.
TracedTimeout
Wraps a future with a timeout that also captures [SpanTrace]s of whatever was still pending when it fired – see timeout.

Functions§

timeout
Drive fut to completion, limiting its run time to duration. If fut doesn’t finish in time, returns TimeoutElapsed with a trace of every await point still pending at that moment.