| 1 | //! Additional utilities for tracking time. |
| 2 | //! |
| 3 | //! This module provides additional utilities for executing code after a set period |
| 4 | //! of time. Currently there is only one: |
| 5 | //! |
| 6 | //! * `DelayQueue`: A queue where items are returned once the requested delay |
| 7 | //! has expired. |
| 8 | //! |
| 9 | //! This type must be used from within the context of the `Runtime`. |
| 10 | |
| 11 | use std::time::Duration; |
| 12 | |
| 13 | mod wheel; |
| 14 | |
| 15 | pub mod delay_queue; |
| 16 | |
| 17 | #[doc (inline)] |
| 18 | pub use delay_queue::DelayQueue; |
| 19 | |
| 20 | // ===== Internal utils ===== |
| 21 | |
| 22 | enum Round { |
| 23 | Up, |
| 24 | Down, |
| 25 | } |
| 26 | |
| 27 | /// Convert a `Duration` to milliseconds, rounding up and saturating at |
| 28 | /// `u64::MAX`. |
| 29 | /// |
| 30 | /// The saturating is fine because `u64::MAX` milliseconds are still many |
| 31 | /// million years. |
| 32 | #[inline ] |
| 33 | fn ms(duration: Duration, round: Round) -> u64 { |
| 34 | const NANOS_PER_MILLI: u32 = 1_000_000; |
| 35 | const MILLIS_PER_SEC: u64 = 1_000; |
| 36 | |
| 37 | // Round up. |
| 38 | let millis = match round { |
| 39 | Round::Up => (duration.subsec_nanos() + NANOS_PER_MILLI - 1) / NANOS_PER_MILLI, |
| 40 | Round::Down => duration.subsec_millis(), |
| 41 | }; |
| 42 | |
| 43 | duration |
| 44 | .as_secs() |
| 45 | .saturating_mul(MILLIS_PER_SEC) |
| 46 | .saturating_add(u64::from(millis)) |
| 47 | } |
| 48 | |