async_graphql/
runtime.rs

1//! Runtime abstraction traits
2
3use std::time::Duration;
4
5#[cfg(feature = "tokio")]
6mod tokio {
7    use std::time::Duration;
8
9    use futures_util::{
10        FutureExt,
11        future::BoxFuture,
12        task::{FutureObj, Spawn, SpawnError},
13    };
14    use tokio::runtime::Handle;
15
16    use crate::runtime::Timer;
17
18    /// A Tokio-backed implementation of [`Spawn`]
19    ///
20    /// We use this abstraction across the crate for spawning tasks onto the
21    /// runtime
22    pub struct TokioSpawner {
23        handle: Handle,
24    }
25
26    impl TokioSpawner {
27        /// Construct a spawner that obtains a handle of the current runtime
28        ///
29        /// # Panics
30        ///
31        /// Panics when used outside of the context of a Tokio runtime
32        pub fn current() -> Self {
33            Self::with_handle(Handle::current())
34        }
35
36        /// Construct a spawner with a handle of a specific runtime
37        pub fn with_handle(handle: Handle) -> Self {
38            Self { handle }
39        }
40    }
41
42    impl Spawn for TokioSpawner {
43        fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> {
44            self.handle.spawn(future);
45            Ok(())
46        }
47    }
48
49    /// A Tokio-backed implementation of the [`Timer`] trait
50    #[derive(Default)]
51    pub struct TokioTimer {
52        _priv: (),
53    }
54
55    impl Timer for TokioTimer {
56        fn delay(&self, duration: Duration) -> BoxFuture<'static, ()> {
57            tokio::time::sleep(duration).boxed()
58        }
59    }
60}
61use futures_util::future::BoxFuture;
62
63#[cfg(feature = "tokio")]
64pub use self::tokio::{TokioSpawner, TokioTimer};
65
66/// Timing facilities required by parts of the crate
67///
68/// The purpose is to make async-graphql integrate nicely with whatever
69/// environment you're in.
70///
71/// Be it Tokio, smol, or even the browser.
72pub trait Timer: Send + Sync + 'static {
73    /// Returns a future that resolves after the specified duration
74    fn delay(&self, duration: Duration) -> BoxFuture<'static, ()>;
75}
76
77const _: Option<&dyn Timer> = None;