libp2p_swarm/
executor.rs

1//! Provides executors for spawning background tasks.
2use std::{future::Future, pin::Pin};
3
4use futures::executor::ThreadPool;
5
6/// Implemented on objects that can run a `Future` in the background.
7///
8/// > **Note**: While it may be tempting to implement this trait on types such as
9/// > [`futures::stream::FuturesUnordered`], please note that passing an `Executor` is
10/// > optional, and that `FuturesUnordered` (or a similar struct) will automatically
11/// > be used as fallback by libp2p. The `Executor` trait should therefore only be
12/// > about running `Future`s on a separate task.
13pub trait Executor {
14    /// Run the given future in the background until it ends.
15    #[track_caller]
16    fn exec(&self, future: Pin<Box<dyn Future<Output = ()> + Send>>);
17}
18
19impl<F: Fn(Pin<Box<dyn Future<Output = ()> + Send>>)> Executor for F {
20    fn exec(&self, f: Pin<Box<dyn Future<Output = ()> + Send>>) {
21        self(f)
22    }
23}
24
25impl Executor for ThreadPool {
26    fn exec(&self, future: Pin<Box<dyn Future<Output = ()> + Send>>) {
27        self.spawn_ok(future)
28    }
29}
30
31#[cfg(all(
32    feature = "tokio",
33    not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown"))
34))]
35#[derive(Default, Debug, Clone, Copy)]
36pub(crate) struct TokioExecutor;
37#[cfg(all(
38    feature = "tokio",
39    not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown"))
40))]
41impl Executor for TokioExecutor {
42    fn exec(&self, future: Pin<Box<dyn Future<Output = ()> + Send>>) {
43        tokio::spawn(future);
44    }
45}
46
47#[cfg(all(
48    feature = "async-std",
49    not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown"))
50))]
51#[derive(Default, Debug, Clone, Copy)]
52pub(crate) struct AsyncStdExecutor;
53#[cfg(all(
54    feature = "async-std",
55    not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown"))
56))]
57impl Executor for AsyncStdExecutor {
58    fn exec(&self, future: Pin<Box<dyn Future<Output = ()> + Send>>) {
59        async_std::task::spawn(future);
60    }
61}
62
63#[cfg(feature = "wasm-bindgen")]
64#[derive(Default, Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
65pub(crate) struct WasmBindgenExecutor;
66#[cfg(feature = "wasm-bindgen")]
67impl Executor for WasmBindgenExecutor {
68    fn exec(&self, future: Pin<Box<dyn Future<Output = ()> + Send>>) {
69        wasm_bindgen_futures::spawn_local(future)
70    }
71}