pub trait Clock: Send + Sync {
// Required methods
fn now(&self) -> Instant;
fn sleep_until(
&self,
deadline: Instant,
cancellation: &Cancellation,
) -> impl Future<Output = OperationResult<()>> + Send;
// Provided methods
fn sleep(
&self,
duration: Duration,
cancellation: &Cancellation,
) -> impl Future<Output = OperationResult<()>> + Send { ... }
fn timeout<FutureType>(
&self,
duration: Duration,
operation: FutureType,
) -> impl Future<Output = Result<FutureType::Output, TimeoutError>> + Send
where FutureType: Future + Send { ... }
}Expand description
Monotonic time and cooperative waits in one scheduler’s clock domain.
Obtain current time through this trait rather than Instant::now() or Instant::elapsed() so simulated and paused clocks remain substitutable. Deadlines from independently advancing clock domains are not interchangeable.
Required Methods§
Sourcefn sleep_until(
&self,
deadline: Instant,
cancellation: &Cancellation,
) -> impl Future<Output = OperationResult<()>> + Send
fn sleep_until( &self, deadline: Instant, cancellation: &Cancellation, ) -> impl Future<Output = OperationResult<()>> + Send
Wait until an absolute deadline, or until cancellation is observed.
Futures are lazy. Pre-cancelled waits return cancellation without registering a timer, including for elapsed deadlines. Otherwise an elapsed deadline can complete immediately; no scheduler yield is promised. Once waiting, expiry wins if expiry and cancellation are observed together. Dropping the future releases its timer registration.
Provided Methods§
Sourcefn sleep(
&self,
duration: Duration,
cancellation: &Cancellation,
) -> impl Future<Output = OperationResult<()>> + Send
fn sleep( &self, duration: Duration, cancellation: &Cancellation, ) -> impl Future<Output = OperationResult<()>> + Send
Wait for a duration measured from the first poll, not construction. An unrepresentable deadline returns io::ErrorKind::InvalidInput.
Sourcefn timeout<FutureType>(
&self,
duration: Duration,
operation: FutureType,
) -> impl Future<Output = Result<FutureType::Output, TimeoutError>> + Send
fn timeout<FutureType>( &self, duration: Duration, operation: FutureType, ) -> impl Future<Output = Result<FutureType::Output, TimeoutError>> + Send
Await an operation for at most a relative duration, preserving its output inside Ok.
The operation is polled first on every poll and wins if both it and the timer are ready, including with a zero duration. The timer starts when the operation first returns Pending; an immediately ready operation reads no clock and registers no timer. Constructing an unpolled timeout polls neither future.
Expiry returns TimeoutError::Elapsed; timer failures, including an unrepresentable deadline, return TimeoutError::Clock. The losing future is dropped before returning. Expiry or timer failure drops the operation without requesting cooperative cancellation or awaiting backend retirement. Accepted I/O can continue after abandonment; callers remain responsible for protocol state and cleanup. This wrapper cannot preempt a long-running poll.
use base_scheduler::{Clock, TimeoutError};
use std::{future::Future, time::Duration};
async fn receive<C: Clock>(
clock: &C,
operation: impl Future<Output = Result<String, &'static str>> + Send,
) {
match clock.timeout(Duration::from_secs(5), operation).await {
Ok(Ok(item)) => println!("Received: {item}"),
Ok(Err(error)) => eprintln!("Receive failed: {error}"),
Err(TimeoutError::Elapsed) => eprintln!("Receive timed out"),
Err(TimeoutError::Clock(error)) => eprintln!("Timer failed: {error}"),
}
}Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".