mod interval;
mod sleep;
mod timeout;
pub use interval::{Interval, MissedTickBehavior};
pub use sleep::{Sleep, ZeroBehavior};
pub use timeout::{timeout, Timeout, TimeoutError};
#[inline]
pub fn sleep(duration: std::time::Duration) -> Sleep {
Sleep::new(duration)
}
#[inline]
pub fn sleep_with_zero_behavior(duration: std::time::Duration, behavior: ZeroBehavior) -> Sleep {
Sleep::new_with_zero_behavior(duration, behavior)
}
#[inline]
pub fn interval(period: std::time::Duration) -> Interval {
Interval::new(period)
}
#[inline]
pub fn sleep_until(deadline: std::time::Instant) -> Sleep {
Sleep::sleep_until(deadline)
}
#[inline]
pub async fn timeout_at<T>(
deadline: std::time::Instant,
future: impl std::future::Future<Output = T>,
) -> Result<T, TimeoutError> {
let dur = deadline.saturating_duration_since(std::time::Instant::now());
timeout(dur, future).await
}
#[inline]
pub fn interval_at(
first_tick_instant: std::time::Instant,
period: std::time::Duration,
) -> Interval {
let mut iv = Interval::new(period);
iv.next_deadline = Some(first_tick_instant);
iv
}
#[cfg(test)]
mod tests {
use super::*;
use crate::driver::AnyDriver;
use std::time::{Duration, Instant};
#[test]
fn sleep_completes() {
let rt = crate::executor::Runtime::new(AnyDriver::new_mock());
rt.block_on(async {
Sleep::new(Duration::from_millis(1)).await;
});
}
#[test]
fn timeout_expires() {
let rt = crate::executor::Runtime::new(AnyDriver::new_mock());
let res = rt.block_on(async {
let never = async {
futures_util::future::pending::<()>().await;
};
timeout(Duration::from_millis(1), never).await
});
assert!(res.is_err());
}
#[test]
fn timeout_succeeds_if_future_completes() {
let rt = crate::executor::Runtime::new(AnyDriver::new_mock());
let res = rt.block_on(async { timeout(Duration::from_secs(1), async { 123usize }).await });
assert_eq!(res, Ok(123usize));
}
#[test]
fn interval_ticks_skip() {
let rt = crate::executor::Runtime::new(AnyDriver::new_mock());
rt.block_on(async {
let mut interval = Interval::new(Duration::from_millis(1));
let _ = interval.tick().await;
let _ = interval.tick().await;
});
}
#[test]
fn interval_catchup_returns_multiple() {
let rt = crate::executor::Runtime::new(AnyDriver::new_mock());
rt.block_on(async {
let mut interval = Interval::new(Duration::from_millis(1));
interval.set_missed_tick_behavior(MissedTickBehavior::CatchUp);
let _ = interval.tick().await;
interval.next_deadline = Some(Instant::now() - Duration::from_millis(10));
let missed = interval.tick().await;
assert!(missed >= 1);
});
}
}