mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-26 16:21:39 +00:00
feat(swarm): Make executor for connection tasks explicit (#3097)
Previously, the executor for connection tasks silently defaulted to a `futures::executor::ThreadPool`. This causes issues such as https://github.com/libp2p/rust-libp2p/issues/2230. With this patch, we force the user to choose, which executor they want to run the connection tasks on which results in overall simpler API with less footguns. Closes #3068.
This commit is contained in:
48
swarm/src/executor.rs
Normal file
48
swarm/src/executor.rs
Normal file
@ -0,0 +1,48 @@
|
||||
use futures::executor::ThreadPool;
|
||||
use std::{future::Future, pin::Pin};
|
||||
|
||||
/// Implemented on objects that can run a `Future` in the background.
|
||||
///
|
||||
/// > **Note**: While it may be tempting to implement this trait on types such as
|
||||
/// > [`futures::stream::FuturesUnordered`], please note that passing an `Executor` is
|
||||
/// > optional, and that `FuturesUnordered` (or a similar struct) will automatically
|
||||
/// > be used as fallback by libp2p. The `Executor` trait should therefore only be
|
||||
/// > about running `Future`s on a separate task.
|
||||
pub trait Executor {
|
||||
/// Run the given future in the background until it ends.
|
||||
fn exec(&self, future: Pin<Box<dyn Future<Output = ()> + Send>>);
|
||||
}
|
||||
|
||||
impl<F: Fn(Pin<Box<dyn Future<Output = ()> + Send>>)> Executor for F {
|
||||
fn exec(&self, f: Pin<Box<dyn Future<Output = ()> + Send>>) {
|
||||
self(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Executor for ThreadPool {
|
||||
fn exec(&self, future: Pin<Box<dyn Future<Output = ()> + Send>>) {
|
||||
self.spawn_ok(future)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "tokio")]
|
||||
#[derive(Default, Debug, Clone, Copy)]
|
||||
pub(crate) struct TokioExecutor;
|
||||
|
||||
#[cfg(feature = "tokio")]
|
||||
impl Executor for TokioExecutor {
|
||||
fn exec(&self, future: Pin<Box<dyn Future<Output = ()> + Send>>) {
|
||||
let _ = tokio::spawn(future);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "async-std")]
|
||||
#[derive(Default, Debug, Clone, Copy)]
|
||||
pub(crate) struct AsyncStdExecutor;
|
||||
|
||||
#[cfg(feature = "async-std")]
|
||||
impl Executor for AsyncStdExecutor {
|
||||
fn exec(&self, future: Pin<Box<dyn Future<Output = ()> + Send>>) {
|
||||
let _ = async_std::task::spawn(future);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user