pub struct CloseBudget { /* private fields */ }Expand description
A finite budget for a shutdown, started once and spent by every phase of it.
Why the type exists. A close has phases — stop admitting work, let
what is already finished reach the peer, then close the sockets and wait
for them to go idle — and each phase’s wait is decided by somebody else’s
network. Without one budget spanning all of them, the length of a close is
whatever the slowest peer makes it: QUIC’s closing and draining periods
last about three times the path’s probe timeout, and ZeroMQ’s ZMQ_LINGER
defaults to infinite, which is why zmq_ctx_term() is known as a place
processes hang (docs/research/zeromq.md §12/P17). A process that must
exit within a budget of its own cannot use an API like that
(decisions/0009 §4.3, §4.4).
So: one budget, taken at the start, and each phase asks how much is left.
A phase that overruns leaves the next one Duration::ZERO rather than a
negative number, which is a bound that still holds rather than a wait that
starts over.
let budget = CloseBudget::start(Duration::from_secs(1));
// First phase waits on `budget.remaining()`, and so does the next.
assert!(budget.remaining() <= Duration::from_secs(1));
assert_eq!(budget.limit(), Duration::from_secs(1));Implementations§
Source§impl CloseBudget
impl CloseBudget
Sourcepub fn start(limit: Duration) -> CloseBudget
pub fn start(limit: Duration) -> CloseBudget
Starts a budget of limit, from now.
Sourcepub const fn limit(&self) -> Duration
pub const fn limit(&self) -> Duration
What the whole budget was, regardless of what is left of it.
Sourcepub fn remaining(&self) -> Duration
pub fn remaining(&self) -> Duration
What is left, saturating at Duration::ZERO: the bound the next
phase of the close gets.