ferroid/runtime/
tokio.rs

1use crate::SleepProvider;
2use core::pin::Pin;
3
4/// An implementation of [`SleepProvider`] using Tokio's timer.
5///
6/// This is the default provider for use in async applications built on Tokio.
7pub struct TokioSleep;
8impl SleepProvider for TokioSleep {
9    type Sleep = tokio::time::Sleep;
10
11    fn sleep_for(dur: core::time::Duration) -> Self::Sleep {
12        tokio::time::sleep(dur)
13    }
14}
15
16/// An implementation of [`SleepProvider`] using Tokio's yield.
17///
18/// This strategy avoids timer-based delays by yielding to the scheduler
19/// immediately, which can improve responsiveness in low-concurrency scenarios.
20///
21/// However, it comes at the cost of more frequent rescheduling, which can
22/// result in tighter polling loops and increased CPU usage under load. In
23/// highly concurrent cases, a timer-based sleep (e.g., [`TokioSleep`]) is often
24/// more efficient due to reduced scheduler churn.
25pub struct TokioYield;
26impl SleepProvider for TokioYield {
27    /// Tokio's `yield_now()` returns a private future type, so we must use a
28    /// boxed `dyn Future` to abstract over it.
29    type Sleep = Pin<Box<dyn Future<Output = ()> + Send>>;
30
31    fn sleep_for(_dur: core::time::Duration) -> Self::Sleep {
32        Box::pin(tokio::task::yield_now())
33    }
34}