pub struct Deadline { /* private fields */ }Expand description
A time budget pinned to a monotonic timeline.
A Deadline is a start instant plus a budget; it expires at
start + budget. It never reads the clock — pass now to the query
methods. All arithmetic saturates, so a backwards-moving clock or an
overflowing start + budget cannot panic.
A zero budget expires immediately at start. For the same reason,
Deadline::default (start and budget both 0) is already expired —
it is not an “infinite” deadline.
Implementations§
Source§impl Deadline
impl Deadline
Sourcepub const fn new(start: u64, budget: u64) -> Self
pub const fn new(start: u64, budget: u64) -> Self
Creates a deadline that expires budget units after start.
Sourcepub const fn expiry(&self) -> u64
pub const fn expiry(&self) -> u64
The instant the deadline expires, i.e. start + budget (saturating).
Examples found in repository?
9fn main() {
10 // A 1-second budget for the whole operation.
11 let policy = Timeout::new(1_000);
12
13 // Pretend the operation starts at t = 0.
14 let deadline: Deadline = policy.start(0);
15 println!(
16 "budget: {} ms, expires at t = {}",
17 policy.budget(),
18 deadline.expiry()
19 );
20
21 // A fake monotonic clock and a fixed retry delay.
22 let mut now = 0;
23 let attempt_cost = 250; // each attempt + wait advances the clock by this much
24
25 for attempt in 1.. {
26 match deadline.check(now) {
27 None => {
28 println!(
29 "t = {now}: deadline expired, giving up after {} attempts",
30 attempt - 1
31 );
32 break;
33 }
34 Some(remaining) => {
35 // Never wait longer than the time left in the budget.
36 let wait = deadline.clamp(now, attempt_cost);
37 println!("t = {now}: attempt {attempt} ({remaining} ms left, waiting {wait} ms)");
38 now += attempt_cost;
39 }
40 }
41 }
42}Sourcepub const fn elapsed(&self, now: u64) -> u64
pub const fn elapsed(&self, now: u64) -> u64
Time elapsed since start at now.
Saturates to 0 when now is before start.
Sourcepub const fn remaining(&self, now: u64) -> u64
pub const fn remaining(&self, now: u64) -> u64
Time left until expiry at now.
Saturates to 0 once the deadline has expired.
Sourcepub const fn is_expired(&self, now: u64) -> bool
pub const fn is_expired(&self, now: u64) -> bool
Whether the deadline has expired at now (now >= expiry).
Sourcepub const fn check(&self, now: u64) -> Option<u64>
pub const fn check(&self, now: u64) -> Option<u64>
Returns the remaining time if the deadline is still live at now, or
None once it has expired.
Examples found in repository?
9fn main() {
10 // A 1-second budget for the whole operation.
11 let policy = Timeout::new(1_000);
12
13 // Pretend the operation starts at t = 0.
14 let deadline: Deadline = policy.start(0);
15 println!(
16 "budget: {} ms, expires at t = {}",
17 policy.budget(),
18 deadline.expiry()
19 );
20
21 // A fake monotonic clock and a fixed retry delay.
22 let mut now = 0;
23 let attempt_cost = 250; // each attempt + wait advances the clock by this much
24
25 for attempt in 1.. {
26 match deadline.check(now) {
27 None => {
28 println!(
29 "t = {now}: deadline expired, giving up after {} attempts",
30 attempt - 1
31 );
32 break;
33 }
34 Some(remaining) => {
35 // Never wait longer than the time left in the budget.
36 let wait = deadline.clamp(now, attempt_cost);
37 println!("t = {now}: attempt {attempt} ({remaining} ms left, waiting {wait} ms)");
38 now += attempt_cost;
39 }
40 }
41 }
42}Sourcepub const fn allows(&self, now: u64, duration: u64) -> bool
pub const fn allows(&self, now: u64, duration: u64) -> bool
Whether an operation that needs duration units can finish before the
deadline at now (remaining(now) >= duration).
A duration of 0 is always allowed, even once the deadline has
expired.
Sourcepub const fn clamp(&self, now: u64, duration: u64) -> u64
pub const fn clamp(&self, now: u64, duration: u64) -> u64
Caps duration so it does not run past the deadline: the smaller of
duration and remaining at now.
Handy for bounding a backoff delay by the time left in the budget.
Examples found in repository?
9fn main() {
10 // A 1-second budget for the whole operation.
11 let policy = Timeout::new(1_000);
12
13 // Pretend the operation starts at t = 0.
14 let deadline: Deadline = policy.start(0);
15 println!(
16 "budget: {} ms, expires at t = {}",
17 policy.budget(),
18 deadline.expiry()
19 );
20
21 // A fake monotonic clock and a fixed retry delay.
22 let mut now = 0;
23 let attempt_cost = 250; // each attempt + wait advances the clock by this much
24
25 for attempt in 1.. {
26 match deadline.check(now) {
27 None => {
28 println!(
29 "t = {now}: deadline expired, giving up after {} attempts",
30 attempt - 1
31 );
32 break;
33 }
34 Some(remaining) => {
35 // Never wait longer than the time left in the budget.
36 let wait = deadline.clamp(now, attempt_cost);
37 println!("t = {now}: attempt {attempt} ({remaining} ms left, waiting {wait} ms)");
38 now += attempt_cost;
39 }
40 }
41 }
42}