The reactor reuses the shared :class:flare.runtime.timer_wheel.TimerWheel
for every timeout it needs to track. The wheel's per-entry payload is a
single UInt64 token, which means each in-flight QUIC timeout needs a
self-describing encoding that:
- tells the reactor which kind of timeout fired (PTO vs idle vs
ack-delay) so the right :class:
flare.quic.server.QuicConnection
callback runs, and
- tells it which connection slot the timeout belongs to so the
right :class:
QuicConnection in the listener slab gets the call.
encode_timer_token(kind, slot) packs the two values into the high +
low halves of the UInt64 token:
| 63 32 | 31 0 |
| KIND (UInt32) | SLOT (UInt32) |
decode_timer_token(token) -> (kind, slot) is the inverse. The split
keeps both fields wide enough for any reasonable QUIC server (4
billion concurrent connections, 4 billion timer kinds) while letting
the reactor dispatch with a single arithmetic comparison on the
high-half kind.
Three kinds ship here; the comments name the RFC sections
the reactor dispatch wires each one against:
- :data:
TIMER_KIND_PTO -- RFC 9002 §6.2 PTO probe timer.
- :data:
TIMER_KIND_IDLE -- RFC 9000 §10.1 idle timeout.
- :data:
TIMER_KIND_ACK_DELAY -- RFC 9000 §13.2 deferred-ACK timer.
Additional kinds (key-update, path-validation challenge, etc.) plug
into the same encoding; the dispatcher checks kind against the
known constants and falls back to a debug log for unknown kinds.