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(feature = "wasm-bindgen")]
48#[derive(Default, Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
49pub(crate) struct WasmBindgenExecutor;
50#[cfg(feature = "wasm-bindgen")]
51impl Executor for WasmBindgenExecutor {
52    fn exec(&self, future: Pin<Box<dyn Future<Output = ()> + Send>>) {
53        wasm_bindgen_futures::spawn_local(future)
54    }
55}