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    fn exec(&self, future: Pin<Box<dyn Future<Output = ()> + Send>>);
15}
16
17impl<F: Fn(Pin<Box<dyn Future<Output = ()> + Send>>)> Executor for F {
18    fn exec(&self, f: Pin<Box<dyn Future<Output = ()> + Send>>) {
19        self(f)
20    }
21}
22
23impl Executor for ThreadPool {
24    fn exec(&self, future: Pin<Box<dyn Future<Output = ()> + Send>>) {
25        self.spawn_ok(future)
26    }
27}
28
29#[cfg(all(
30    feature = "tokio",
31    not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown"))
32))]
33#[derive(Default, Debug, Clone, Copy)]
34pub(crate) struct TokioExecutor;
35#[cfg(all(
36    feature = "tokio",
37    not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown"))
38))]
39impl Executor for TokioExecutor {
40    fn exec(&self, future: Pin<Box<dyn Future<Output = ()> + Send>>) {
41        tokio::spawn(future);
42    }
43}
44
45#[cfg(all(
46    feature = "async-std",
47    not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown"))
48))]
49#[derive(Default, Debug, Clone, Copy)]
50pub(crate) struct AsyncStdExecutor;
51#[cfg(all(
52    feature = "async-std",
53    not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown"))
54))]
55impl Executor for AsyncStdExecutor {
56    fn exec(&self, future: Pin<Box<dyn Future<Output = ()> + Send>>) {
57        async_std::task::spawn(future);
58    }
59}
60
61#[cfg(feature = "wasm-bindgen")]
62#[derive(Default, Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
63pub(crate) struct WasmBindgenExecutor;
64#[cfg(feature = "wasm-bindgen")]
65impl Executor for WasmBindgenExecutor {
66    fn exec(&self, future: Pin<Box<dyn Future<Output = ()> + Send>>) {
67        wasm_bindgen_futures::spawn_local(future)
68    }
69}