libp2p_swarm/
executor.rs

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