Skip to main content

trillium_server_common/runtime/
runtime_trait.rs

1use super::{DroppableFuture, Runtime};
2use futures_lite::{FutureExt, Stream};
3use std::{future::Future, time::Duration};
4
5/// A trait that covers async runtime behavior.
6///
7/// You likely do not need to name this type. For a type-erased runtime, see [`Runtime`]
8pub trait RuntimeTrait: Into<Runtime> + Clone + Send + Sync + 'static {
9    /// Spawn a future on the runtime, returning a future that has detach-on-drop semantics
10    ///
11    /// As the various runtimes each has different behavior for spawn, implementations of this trait
12    /// are expected to conform to the following:
13    ///
14    /// * detach on drop: If the returned [`DroppableFuture`] is dropped immediately, the task will
15    ///   continue to execute until completion.
16    ///
17    /// * unwinding: If the spawned future panics, this must not propagate to the join handle.
18    ///   Instead, the awaiting the join handle returns None in case of panic.
19    fn spawn<Fut>(
20        &self,
21        fut: Fut,
22    ) -> DroppableFuture<impl Future<Output = Option<Fut::Output>> + Send + 'static>
23    where
24        Fut: Future + Send + 'static,
25        Fut::Output: Send + 'static;
26
27    /// Wake in this amount of wall time
28    fn delay(&self, duration: Duration) -> impl Future<Output = ()> + Send;
29
30    /// Returns a [`Stream`] that yields a `()` on the provided period
31    fn interval(&self, period: Duration) -> impl Stream<Item = ()> + Send + 'static;
32
33    /// Runtime implementation hook for blocking on a top level future.
34    fn block_on<Fut>(&self, fut: Fut) -> Fut::Output
35    where
36        Fut: Future;
37
38    /// Race a future against the provided duration, returning None in case of timeout.
39    fn timeout<'runtime, 'fut, Fut>(
40        &'runtime self,
41        duration: Duration,
42        fut: Fut,
43    ) -> impl Future<Output = Option<Fut::Output>> + Send + 'fut
44    where
45        Fut: Future + Send + 'fut,
46        Fut::Output: Send + 'static,
47        'runtime: 'fut,
48    {
49        async move { Some(fut.await) }.race(async move {
50            self.delay(duration).await;
51            None
52        })
53    }
54
55    /// trap and return a [`Stream`] of signals that match the provided signals
56    fn hook_signals(
57        &self,
58        signals: impl IntoIterator<Item = i32>,
59    ) -> impl Stream<Item = i32> + Send + 'static {
60        let _ = signals;
61        futures_lite::stream::empty()
62    }
63}