Skip to main content

phantom_protocol/runtime/
tokio_runtime.rs

1//! [`TokioRuntime`] — default [`Runtime`] implementation backed by tokio.
2//!
3//! Preserves today's behavior verbatim (`tokio::spawn`,
4//! `tokio::time::sleep`, `std::time::Instant`, `std::time::SystemTime`).
5//! Call sites that take an `Arc<dyn Runtime>` can substitute this without
6//! observable behavioral change.
7
8use std::time::{Duration, Instant, SystemTime};
9
10use tokio::task::JoinHandle;
11
12use super::{BoxFuture, Runtime, SpawnHandle, SpawnHandleInner};
13
14/// Tokio-backed [`Runtime`]. Zero-sized — construct with `TokioRuntime`
15/// and wrap in `Arc` to share across tasks.
16#[derive(Clone, Copy, Default)]
17pub struct TokioRuntime;
18
19impl Runtime for TokioRuntime {
20    fn spawn(&self, fut: BoxFuture<()>) -> SpawnHandle {
21        let handle: JoinHandle<()> = tokio::spawn(fut);
22        SpawnHandle::from_inner(TokioSpawnHandle { handle })
23    }
24
25    fn sleep(&self, duration: Duration) -> BoxFuture<()> {
26        Box::pin(tokio::time::sleep(duration))
27    }
28
29    fn now_monotonic(&self) -> Instant {
30        Instant::now()
31    }
32
33    fn now_wall_clock(&self) -> SystemTime {
34        SystemTime::now()
35    }
36}
37
38/// Inner type behind a [`SpawnHandle`] produced by [`TokioRuntime`]. Wraps
39/// a `tokio::task::JoinHandle` so the public-facing handle stays opaque.
40pub(super) struct TokioSpawnHandle {
41    handle: JoinHandle<()>,
42}
43
44impl SpawnHandleInner for TokioSpawnHandle {
45    fn abort(&self) {
46        self.handle.abort();
47    }
48
49    fn is_finished(&self) -> bool {
50        self.handle.is_finished()
51    }
52}