use std::future::Future;
pub use lgwks_deps::tokio::time::error::Elapsed;
pub use lgwks_deps::tokio::time::{Instant, MissedTickBehavior, interval, interval_at};
pub use std::time::Duration;
pub use super::clock::{Clock, ClockError, ClockSnapshot, TimeSource, WallClock};
pub async fn sleep(duration: Duration) {
lgwks_deps::tokio::time::sleep(duration).await;
}
pub async fn sleep_until(deadline: Instant) {
lgwks_deps::tokio::time::sleep_until(deadline).await;
}
pub async fn timeout<F: Future>(duration: Duration, future: F) -> Result<F::Output, Elapsed> {
lgwks_deps::tokio::time::timeout(duration, future).await
}
pub async fn timeout_at<F: Future>(deadline: Instant, future: F) -> Result<F::Output, Elapsed> {
lgwks_deps::tokio::time::timeout_at(deadline, future).await
}
#[derive(Debug, Clone, Copy)]
pub struct Deadline<'a> {
clock: &'a Clock,
budget: Duration,
started_on: Duration,
started: std::time::Instant,
}
impl<'a> Deadline<'a> {
#[must_use]
pub fn after(clock: &'a Clock, budget: Duration) -> Self {
Self {
clock,
budget,
started_on: clock.now(),
started: std::time::Instant::now(),
}
}
#[must_use]
pub fn expired(clock: &'a Clock) -> Self {
Self::after(clock, Duration::ZERO)
}
#[must_use]
pub const fn clock(&self) -> &'a Clock {
self.clock
}
#[must_use]
pub const fn budget(&self) -> Duration {
self.budget
}
#[must_use]
pub fn elapsed(&self) -> Duration {
self.clock.now().saturating_sub(self.started_on)
}
#[must_use]
pub fn remaining(&self) -> Duration {
self.budget.saturating_sub(self.elapsed())
}
#[must_use]
pub fn is_exhausted(&self) -> bool {
self.elapsed() >= self.budget
}
#[must_use]
pub fn watchdog(&self) -> WallClock {
WallClock::from_instant(self.started)
}
#[must_use]
pub fn watchdog_exceeded(&self, limit: Duration) -> bool {
self.watchdog().elapsed() >= limit
}
#[must_use]
pub fn snapshot(&self) -> ClockSnapshot {
self.clock.snapshot()
}
}