mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-05-16 21:01:19 +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:
parent
d8fe7bf49f
commit
d5ea93dd71
@ -47,7 +47,8 @@ full = [
|
|||||||
"websocket",
|
"websocket",
|
||||||
"yamux",
|
"yamux",
|
||||||
]
|
]
|
||||||
async-std = ["libp2p-mdns?/async-io", "libp2p-tcp?/async-io", "libp2p-dns?/async-std", "libp2p-quic?/async-std"]
|
|
||||||
|
async-std = ["libp2p-swarm/async-std", "libp2p-mdns?/async-io", "libp2p-tcp?/async-io", "libp2p-dns?/async-std", "libp2p-quic?/async-std"]
|
||||||
autonat = ["dep:libp2p-autonat"]
|
autonat = ["dep:libp2p-autonat"]
|
||||||
dcutr = ["dep:libp2p-dcutr", "libp2p-metrics?/dcutr"]
|
dcutr = ["dep:libp2p-dcutr", "libp2p-metrics?/dcutr"]
|
||||||
deflate = ["dep:libp2p-deflate"]
|
deflate = ["dep:libp2p-deflate"]
|
||||||
@ -74,7 +75,7 @@ rsa = ["libp2p-core/rsa"]
|
|||||||
secp256k1 = ["libp2p-core/secp256k1"]
|
secp256k1 = ["libp2p-core/secp256k1"]
|
||||||
serde = ["libp2p-core/serde", "libp2p-kad?/serde", "libp2p-gossipsub?/serde"]
|
serde = ["libp2p-core/serde", "libp2p-kad?/serde", "libp2p-gossipsub?/serde"]
|
||||||
tcp = ["dep:libp2p-tcp"]
|
tcp = ["dep:libp2p-tcp"]
|
||||||
tokio = ["libp2p-mdns?/tokio", "libp2p-tcp?/tokio", "libp2p-dns?/tokio", "libp2p-quic?/tokio"]
|
tokio = ["libp2p-swarm/tokio", "libp2p-mdns?/tokio", "libp2p-tcp?/tokio", "libp2p-dns?/tokio", "libp2p-quic?/tokio"]
|
||||||
uds = ["dep:libp2p-uds"]
|
uds = ["dep:libp2p-uds"]
|
||||||
wasm-bindgen = ["futures-timer/wasm-bindgen", "instant/wasm-bindgen", "getrandom/js"]
|
wasm-bindgen = ["futures-timer/wasm-bindgen", "instant/wasm-bindgen", "getrandom/js"]
|
||||||
wasm-ext = ["dep:libp2p-wasm-ext"]
|
wasm-ext = ["dep:libp2p-wasm-ext"]
|
||||||
|
@ -4,8 +4,11 @@
|
|||||||
|
|
||||||
- Hide `prost::Error` from public API in `FromEnvelopeError::InvalidPeerRecord` and `signed_envelope::DecodingError`. See [PR 3058].
|
- Hide `prost::Error` from public API in `FromEnvelopeError::InvalidPeerRecord` and `signed_envelope::DecodingError`. See [PR 3058].
|
||||||
|
|
||||||
|
- Move `Executor` to `libp2p-swarm`. See [PR 3097].
|
||||||
|
|
||||||
[PR 3031]: https://github.com/libp2p/rust-libp2p/pull/3031
|
[PR 3031]: https://github.com/libp2p/rust-libp2p/pull/3031
|
||||||
[PR 3058]: https://github.com/libp2p/rust-libp2p/pull/3058
|
[PR 3058]: https://github.com/libp2p/rust-libp2p/pull/3058
|
||||||
|
[PR 3097]: https://github.com/libp2p/rust-libp2p/pull/3097
|
||||||
|
|
||||||
# 0.37.0
|
# 0.37.0
|
||||||
|
|
||||||
|
@ -83,23 +83,3 @@ pub use upgrade::{InboundUpgrade, OutboundUpgrade, ProtocolName, UpgradeError, U
|
|||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
pub struct DecodeError(prost::DecodeError);
|
pub struct DecodeError(prost::DecodeError);
|
||||||
|
|
||||||
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 in the background.
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -39,7 +39,7 @@ use libp2p::{
|
|||||||
TokioMdns,
|
TokioMdns,
|
||||||
},
|
},
|
||||||
mplex, noise,
|
mplex, noise,
|
||||||
swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent},
|
swarm::{NetworkBehaviour, SwarmEvent},
|
||||||
tcp, Multiaddr, PeerId, Transport,
|
tcp, Multiaddr, PeerId, Transport,
|
||||||
};
|
};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
@ -97,23 +97,12 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a Swarm to manage peers and events.
|
// Create a Swarm to manage peers and events.
|
||||||
let mut swarm = {
|
let mdns = TokioMdns::new(Default::default())?;
|
||||||
let mdns = TokioMdns::new(Default::default())?;
|
let behaviour = MyBehaviour {
|
||||||
let mut behaviour = MyBehaviour {
|
floodsub: Floodsub::new(peer_id),
|
||||||
floodsub: Floodsub::new(peer_id),
|
mdns,
|
||||||
mdns,
|
|
||||||
};
|
|
||||||
|
|
||||||
behaviour.floodsub.subscribe(floodsub_topic.clone());
|
|
||||||
|
|
||||||
SwarmBuilder::new(transport, behaviour, peer_id)
|
|
||||||
// We want the connection background tasks to be spawned
|
|
||||||
// onto the tokio runtime.
|
|
||||||
.executor(Box::new(|fut| {
|
|
||||||
tokio::spawn(fut);
|
|
||||||
}))
|
|
||||||
.build()
|
|
||||||
};
|
};
|
||||||
|
let mut swarm = libp2p_swarm::Swarm::with_tokio_executor(transport, behaviour, peer_id);
|
||||||
|
|
||||||
// Reach out to another node if specified
|
// Reach out to another node if specified
|
||||||
if let Some(to_dial) = std::env::args().nth(1) {
|
if let Some(to_dial) = std::env::args().nth(1) {
|
||||||
|
@ -115,7 +115,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
behaviour.floodsub.subscribe(floodsub_topic.clone());
|
behaviour.floodsub.subscribe(floodsub_topic.clone());
|
||||||
Swarm::new(transport, behaviour, local_peer_id)
|
Swarm::with_threadpool_executor(transport, behaviour, local_peer_id)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Reach out to another node if specified
|
// Reach out to another node if specified
|
||||||
|
@ -99,7 +99,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
let kademlia = Kademlia::new(local_peer_id, store);
|
let kademlia = Kademlia::new(local_peer_id, store);
|
||||||
let mdns = Mdns::new(MdnsConfig::default())?;
|
let mdns = Mdns::new(MdnsConfig::default())?;
|
||||||
let behaviour = MyBehaviour { kademlia, mdns };
|
let behaviour = MyBehaviour { kademlia, mdns };
|
||||||
Swarm::new(transport, behaviour, local_peer_id)
|
Swarm::with_async_std_executor(transport, behaviour, local_peer_id)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Read full lines from stdin
|
// Read full lines from stdin
|
||||||
|
@ -219,9 +219,7 @@ mod network {
|
|||||||
ProtocolSupport, RequestId, RequestResponse, RequestResponseCodec, RequestResponseEvent,
|
ProtocolSupport, RequestId, RequestResponse, RequestResponseCodec, RequestResponseEvent,
|
||||||
RequestResponseMessage, ResponseChannel,
|
RequestResponseMessage, ResponseChannel,
|
||||||
};
|
};
|
||||||
use libp2p::swarm::{
|
use libp2p::swarm::{ConnectionHandlerUpgrErr, NetworkBehaviour, Swarm, SwarmEvent};
|
||||||
ConnectionHandlerUpgrErr, NetworkBehaviour, Swarm, SwarmBuilder, SwarmEvent,
|
|
||||||
};
|
|
||||||
use std::collections::{hash_map, HashMap, HashSet};
|
use std::collections::{hash_map, HashMap, HashSet};
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
@ -252,7 +250,7 @@ mod network {
|
|||||||
|
|
||||||
// Build the Swarm, connecting the lower layer transport logic with the
|
// Build the Swarm, connecting the lower layer transport logic with the
|
||||||
// higher layer network behaviour logic.
|
// higher layer network behaviour logic.
|
||||||
let swarm = SwarmBuilder::new(
|
let swarm = Swarm::with_threadpool_executor(
|
||||||
libp2p::development_transport(id_keys).await?,
|
libp2p::development_transport(id_keys).await?,
|
||||||
ComposedBehaviour {
|
ComposedBehaviour {
|
||||||
kademlia: Kademlia::new(peer_id, MemoryStore::new(peer_id)),
|
kademlia: Kademlia::new(peer_id, MemoryStore::new(peer_id)),
|
||||||
@ -263,8 +261,7 @@ mod network {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
peer_id,
|
peer_id,
|
||||||
)
|
);
|
||||||
.build();
|
|
||||||
|
|
||||||
let (command_sender, command_receiver) = mpsc::channel(0);
|
let (command_sender, command_receiver) = mpsc::channel(0);
|
||||||
let (event_sender, event_receiver) = mpsc::channel(0);
|
let (event_sender, event_receiver) = mpsc::channel(0);
|
||||||
|
@ -110,7 +110,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
let mut swarm = {
|
let mut swarm = {
|
||||||
let mdns = Mdns::new(MdnsConfig::default())?;
|
let mdns = Mdns::new(MdnsConfig::default())?;
|
||||||
let behaviour = MyBehaviour { gossipsub, mdns };
|
let behaviour = MyBehaviour { gossipsub, mdns };
|
||||||
Swarm::new(transport, behaviour, local_peer_id)
|
Swarm::with_async_std_executor(transport, behaviour, local_peer_id)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Read full lines from stdin
|
// Read full lines from stdin
|
||||||
|
@ -68,7 +68,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
behaviour.add_address(&PeerId::from_str(peer)?, bootaddr.clone());
|
behaviour.add_address(&PeerId::from_str(peer)?, bootaddr.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
Swarm::new(transport, behaviour, local_peer_id)
|
Swarm::with_async_std_executor(transport, behaviour, local_peer_id)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Order Kademlia to search for a peer.
|
// Order Kademlia to search for a peer.
|
||||||
|
@ -204,7 +204,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
println!("Subscribing to {gossipsub_topic:?}");
|
println!("Subscribing to {gossipsub_topic:?}");
|
||||||
behaviour.gossipsub.subscribe(&gossipsub_topic).unwrap();
|
behaviour.gossipsub.subscribe(&gossipsub_topic).unwrap();
|
||||||
Swarm::new(transport, behaviour, local_peer_id)
|
Swarm::with_async_std_executor(transport, behaviour, local_peer_id)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Reach out to other nodes if specified
|
// Reach out to other nodes if specified
|
||||||
|
@ -45,7 +45,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
// Create a Swarm that establishes connections through the given transport.
|
// Create a Swarm that establishes connections through the given transport.
|
||||||
// Note that the MDNS behaviour itself will not actually inititiate any connections,
|
// Note that the MDNS behaviour itself will not actually inititiate any connections,
|
||||||
// as it only uses UDP.
|
// as it only uses UDP.
|
||||||
let mut swarm = Swarm::new(transport, behaviour, peer_id);
|
let mut swarm = Swarm::with_async_std_executor(transport, behaviour, peer_id);
|
||||||
swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;
|
swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -54,7 +54,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
let transport = libp2p::development_transport(local_key).await?;
|
let transport = libp2p::development_transport(local_key).await?;
|
||||||
|
|
||||||
let mut swarm = Swarm::new(transport, Behaviour::default(), local_peer_id);
|
let mut swarm = Swarm::with_async_std_executor(transport, Behaviour::default(), local_peer_id);
|
||||||
|
|
||||||
// Tell the swarm to listen on all interfaces and a random, OS-assigned
|
// Tell the swarm to listen on all interfaces and a random, OS-assigned
|
||||||
// port.
|
// port.
|
||||||
|
@ -70,7 +70,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
let local_peer_id = PeerId::from(local_key.public());
|
let local_peer_id = PeerId::from(local_key.public());
|
||||||
info!("Local peer id: {:?}", local_peer_id);
|
info!("Local peer id: {:?}", local_peer_id);
|
||||||
|
|
||||||
let mut swarm = Swarm::new(
|
let mut swarm = Swarm::without_executor(
|
||||||
block_on(libp2p::development_transport(local_key))?,
|
block_on(libp2p::development_transport(local_key))?,
|
||||||
Behaviour::default(),
|
Behaviour::default(),
|
||||||
local_peer_id,
|
local_peer_id,
|
||||||
|
@ -61,8 +61,10 @@ fn transport_upgrade() {
|
|||||||
|
|
||||||
let listen_addr = Multiaddr::from(Protocol::Memory(random::<u64>()));
|
let listen_addr = Multiaddr::from(Protocol::Memory(random::<u64>()));
|
||||||
|
|
||||||
let mut dialer = Swarm::new(dialer_transport, dummy::Behaviour, dialer_id);
|
let mut dialer =
|
||||||
let mut listener = Swarm::new(listener_transport, dummy::Behaviour, listener_id);
|
Swarm::with_async_std_executor(dialer_transport, dummy::Behaviour, dialer_id);
|
||||||
|
let mut listener =
|
||||||
|
Swarm::with_async_std_executor(listener_transport, dummy::Behaviour, listener_id);
|
||||||
|
|
||||||
listener.listen_on(listen_addr).unwrap();
|
listener.listen_on(listen_addr).unwrap();
|
||||||
let (addr_sender, addr_receiver) = oneshot::channel();
|
let (addr_sender, addr_receiver) = oneshot::channel();
|
||||||
|
@ -67,7 +67,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
let behaviour = Behaviour::new(local_key.public());
|
let behaviour = Behaviour::new(local_key.public());
|
||||||
|
|
||||||
let mut swarm = Swarm::new(transport, behaviour, local_peer_id);
|
let mut swarm = Swarm::with_async_std_executor(transport, behaviour, local_peer_id);
|
||||||
swarm.listen_on(
|
swarm.listen_on(
|
||||||
Multiaddr::empty()
|
Multiaddr::empty()
|
||||||
.with(Protocol::Ip4(Ipv4Addr::UNSPECIFIED))
|
.with(Protocol::Ip4(Ipv4Addr::UNSPECIFIED))
|
||||||
|
@ -57,7 +57,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
let behaviour = Behaviour::new(local_key.public());
|
let behaviour = Behaviour::new(local_key.public());
|
||||||
|
|
||||||
let mut swarm = Swarm::new(transport, behaviour, local_peer_id);
|
let mut swarm = Swarm::with_async_std_executor(transport, behaviour, local_peer_id);
|
||||||
swarm.listen_on(
|
swarm.listen_on(
|
||||||
Multiaddr::empty()
|
Multiaddr::empty()
|
||||||
.with(Protocol::Ip4(Ipv4Addr::UNSPECIFIED))
|
.with(Protocol::Ip4(Ipv4Addr::UNSPECIFIED))
|
||||||
|
@ -40,7 +40,7 @@ async fn init_swarm(config: Config) -> Swarm<Behaviour> {
|
|||||||
let local_id = PeerId::from_public_key(&keypair.public());
|
let local_id = PeerId::from_public_key(&keypair.public());
|
||||||
let transport = development_transport(keypair).await.unwrap();
|
let transport = development_transport(keypair).await.unwrap();
|
||||||
let behaviour = Behaviour::new(local_id, config);
|
let behaviour = Behaviour::new(local_id, config);
|
||||||
Swarm::new(transport, behaviour, local_id)
|
Swarm::with_async_std_executor(transport, behaviour, local_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn spawn_server(kill: oneshot::Receiver<()>) -> (PeerId, Multiaddr) {
|
async fn spawn_server(kill: oneshot::Receiver<()>) -> (PeerId, Multiaddr) {
|
||||||
|
@ -39,7 +39,7 @@ async fn init_swarm(config: Config) -> Swarm<Behaviour> {
|
|||||||
let local_id = PeerId::from_public_key(&keypair.public());
|
let local_id = PeerId::from_public_key(&keypair.public());
|
||||||
let transport = development_transport(keypair).await.unwrap();
|
let transport = development_transport(keypair).await.unwrap();
|
||||||
let behaviour = Behaviour::new(local_id, config);
|
let behaviour = Behaviour::new(local_id, config);
|
||||||
Swarm::new(transport, behaviour, local_id)
|
Swarm::with_async_std_executor(transport, behaviour, local_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn init_server(config: Option<Config>) -> (Swarm<Behaviour>, PeerId, Multiaddr) {
|
async fn init_server(config: Option<Config>) -> (Swarm<Behaviour>, PeerId, Multiaddr) {
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use futures::executor::block_on;
|
use futures::executor::{block_on, ThreadPool};
|
||||||
use futures::future::FutureExt;
|
use futures::future::FutureExt;
|
||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
use libp2p::core::multiaddr::{Multiaddr, Protocol};
|
use libp2p::core::multiaddr::{Multiaddr, Protocol};
|
||||||
@ -155,9 +155,12 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
dcutr: dcutr::behaviour::Behaviour::new(),
|
dcutr: dcutr::behaviour::Behaviour::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut swarm = SwarmBuilder::new(transport, behaviour, local_peer_id)
|
let mut swarm = match ThreadPool::new() {
|
||||||
.dial_concurrency_factor(10_u8.try_into().unwrap())
|
Ok(tp) => SwarmBuilder::with_executor(transport, behaviour, local_peer_id, tp),
|
||||||
.build();
|
Err(_) => SwarmBuilder::without_executor(transport, behaviour, local_peer_id),
|
||||||
|
}
|
||||||
|
.dial_concurrency_factor(10_u8.try_into().unwrap())
|
||||||
|
.build();
|
||||||
|
|
||||||
swarm
|
swarm
|
||||||
.listen_on(
|
.listen_on(
|
||||||
|
@ -98,7 +98,7 @@ fn build_relay() -> Swarm<relay::Relay> {
|
|||||||
|
|
||||||
let transport = build_transport(MemoryTransport::default().boxed(), local_public_key);
|
let transport = build_transport(MemoryTransport::default().boxed(), local_public_key);
|
||||||
|
|
||||||
Swarm::new(
|
Swarm::with_threadpool_executor(
|
||||||
transport,
|
transport,
|
||||||
relay::Relay::new(
|
relay::Relay::new(
|
||||||
local_peer_id,
|
local_peer_id,
|
||||||
@ -122,7 +122,7 @@ fn build_client() -> Swarm<Client> {
|
|||||||
local_public_key,
|
local_public_key,
|
||||||
);
|
);
|
||||||
|
|
||||||
Swarm::new(
|
Swarm::with_threadpool_executor(
|
||||||
transport,
|
transport,
|
||||||
Client {
|
Client {
|
||||||
relay: behaviour,
|
relay: behaviour,
|
||||||
|
@ -171,7 +171,7 @@ fn build_node() -> (Multiaddr, Swarm<Gossipsub>) {
|
|||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let behaviour = Gossipsub::new(MessageAuthenticity::Author(peer_id), config).unwrap();
|
let behaviour = Gossipsub::new(MessageAuthenticity::Author(peer_id), config).unwrap();
|
||||||
let mut swarm = Swarm::new(transport, behaviour, peer_id);
|
let mut swarm = Swarm::without_executor(transport, behaviour, peer_id);
|
||||||
|
|
||||||
let port = 1 + random::<u64>();
|
let port = 1 + random::<u64>();
|
||||||
let mut addr: Multiaddr = Protocol::Memory(port).into();
|
let mut addr: Multiaddr = Protocol::Memory(port).into();
|
||||||
|
@ -55,7 +55,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
local_key.public(),
|
local_key.public(),
|
||||||
));
|
));
|
||||||
|
|
||||||
let mut swarm = Swarm::new(transport, behaviour, local_peer_id);
|
let mut swarm = Swarm::with_async_std_executor(transport, behaviour, local_peer_id);
|
||||||
|
|
||||||
// Tell the swarm to listen on all interfaces and a random, OS-assigned
|
// Tell the swarm to listen on all interfaces and a random, OS-assigned
|
||||||
// port.
|
// port.
|
||||||
|
@ -584,7 +584,7 @@ mod tests {
|
|||||||
let protocol = Behaviour::new(
|
let protocol = Behaviour::new(
|
||||||
Config::new("a".to_string(), pubkey.clone()).with_agent_version("b".to_string()),
|
Config::new("a".to_string(), pubkey.clone()).with_agent_version("b".to_string()),
|
||||||
);
|
);
|
||||||
let swarm = Swarm::new(transport, protocol, pubkey.to_peer_id());
|
let swarm = Swarm::with_async_std_executor(transport, protocol, pubkey.to_peer_id());
|
||||||
(swarm, pubkey)
|
(swarm, pubkey)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -593,7 +593,7 @@ mod tests {
|
|||||||
let protocol = Behaviour::new(
|
let protocol = Behaviour::new(
|
||||||
Config::new("c".to_string(), pubkey.clone()).with_agent_version("d".to_string()),
|
Config::new("c".to_string(), pubkey.clone()).with_agent_version("d".to_string()),
|
||||||
);
|
);
|
||||||
let swarm = Swarm::new(transport, protocol, pubkey.to_peer_id());
|
let swarm = Swarm::with_async_std_executor(transport, protocol, pubkey.to_peer_id());
|
||||||
(swarm, pubkey)
|
(swarm, pubkey)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -661,7 +661,7 @@ mod tests {
|
|||||||
let (mut swarm1, pubkey1) = {
|
let (mut swarm1, pubkey1) = {
|
||||||
let (pubkey, transport) = transport();
|
let (pubkey, transport) = transport();
|
||||||
let protocol = Behaviour::new(Config::new("a".to_string(), pubkey.clone()));
|
let protocol = Behaviour::new(Config::new("a".to_string(), pubkey.clone()));
|
||||||
let swarm = Swarm::new(transport, protocol, pubkey.to_peer_id());
|
let swarm = Swarm::with_async_std_executor(transport, protocol, pubkey.to_peer_id());
|
||||||
(swarm, pubkey)
|
(swarm, pubkey)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -670,7 +670,7 @@ mod tests {
|
|||||||
let protocol = Behaviour::new(
|
let protocol = Behaviour::new(
|
||||||
Config::new("a".to_string(), pubkey.clone()).with_agent_version("b".to_string()),
|
Config::new("a".to_string(), pubkey.clone()).with_agent_version("b".to_string()),
|
||||||
);
|
);
|
||||||
let swarm = Swarm::new(transport, protocol, pubkey.to_peer_id());
|
let swarm = Swarm::with_async_std_executor(transport, protocol, pubkey.to_peer_id());
|
||||||
(swarm, pubkey)
|
(swarm, pubkey)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -742,7 +742,7 @@ mod tests {
|
|||||||
.with_initial_delay(Duration::from_secs(10)),
|
.with_initial_delay(Duration::from_secs(10)),
|
||||||
);
|
);
|
||||||
|
|
||||||
Swarm::new(transport, protocol, pubkey.to_peer_id())
|
Swarm::with_async_std_executor(transport, protocol, pubkey.to_peer_id())
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut swarm2 = {
|
let mut swarm2 = {
|
||||||
@ -751,7 +751,7 @@ mod tests {
|
|||||||
Config::new("a".to_string(), pubkey.clone()).with_agent_version("b".to_string()),
|
Config::new("a".to_string(), pubkey.clone()).with_agent_version("b".to_string()),
|
||||||
);
|
);
|
||||||
|
|
||||||
Swarm::new(transport, protocol, pubkey.to_peer_id())
|
Swarm::with_async_std_executor(transport, protocol, pubkey.to_peer_id())
|
||||||
};
|
};
|
||||||
|
|
||||||
let swarm1_peer_id = *swarm1.local_peer_id();
|
let swarm1_peer_id = *swarm1.local_peer_id();
|
||||||
|
@ -66,7 +66,7 @@ fn build_node_with_config(cfg: KademliaConfig) -> (Multiaddr, TestSwarm) {
|
|||||||
let store = MemoryStore::new(local_id);
|
let store = MemoryStore::new(local_id);
|
||||||
let behaviour = Kademlia::with_config(local_id, store, cfg);
|
let behaviour = Kademlia::with_config(local_id, store, cfg);
|
||||||
|
|
||||||
let mut swarm = Swarm::new(transport, behaviour, local_id);
|
let mut swarm = Swarm::without_executor(transport, behaviour, local_id);
|
||||||
|
|
||||||
let address: Multiaddr = Protocol::Memory(random::<u64>()).into();
|
let address: Multiaddr = Protocol::Memory(random::<u64>()).into();
|
||||||
swarm.listen_on(address.clone()).unwrap();
|
swarm.listen_on(address.clone()).unwrap();
|
||||||
|
@ -62,7 +62,7 @@ async fn create_swarm(config: MdnsConfig) -> Result<Swarm<Mdns>, Box<dyn Error>>
|
|||||||
let peer_id = PeerId::from(id_keys.public());
|
let peer_id = PeerId::from(id_keys.public());
|
||||||
let transport = libp2p::development_transport(id_keys).await?;
|
let transport = libp2p::development_transport(id_keys).await?;
|
||||||
let behaviour = Mdns::new(config)?;
|
let behaviour = Mdns::new(config)?;
|
||||||
let mut swarm = Swarm::new(transport, behaviour, peer_id);
|
let mut swarm = Swarm::with_async_std_executor(transport, behaviour, peer_id);
|
||||||
swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;
|
swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;
|
||||||
Ok(swarm)
|
Ok(swarm)
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ async fn create_swarm(config: MdnsConfig) -> Result<Swarm<TokioMdns>, Box<dyn Er
|
|||||||
let peer_id = PeerId::from(id_keys.public());
|
let peer_id = PeerId::from(id_keys.public());
|
||||||
let transport = libp2p::tokio_development_transport(id_keys)?;
|
let transport = libp2p::tokio_development_transport(id_keys)?;
|
||||||
let behaviour = TokioMdns::new(config)?;
|
let behaviour = TokioMdns::new(config)?;
|
||||||
let mut swarm = Swarm::new(transport, behaviour, peer_id);
|
let mut swarm = Swarm::with_tokio_executor(transport, behaviour, peer_id);
|
||||||
swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;
|
swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;
|
||||||
Ok(swarm)
|
Ok(swarm)
|
||||||
}
|
}
|
||||||
|
@ -43,10 +43,11 @@ fn ping_pong() {
|
|||||||
let cfg = ping::Config::new().with_interval(Duration::from_millis(10));
|
let cfg = ping::Config::new().with_interval(Duration::from_millis(10));
|
||||||
|
|
||||||
let (peer1_id, trans) = mk_transport(muxer);
|
let (peer1_id, trans) = mk_transport(muxer);
|
||||||
let mut swarm1 = Swarm::new(trans, Behaviour::new(cfg.clone()), peer1_id);
|
let mut swarm1 =
|
||||||
|
Swarm::with_async_std_executor(trans, Behaviour::new(cfg.clone()), peer1_id);
|
||||||
|
|
||||||
let (peer2_id, trans) = mk_transport(muxer);
|
let (peer2_id, trans) = mk_transport(muxer);
|
||||||
let mut swarm2 = Swarm::new(trans, Behaviour::new(cfg), peer2_id);
|
let mut swarm2 = Swarm::with_async_std_executor(trans, Behaviour::new(cfg), peer2_id);
|
||||||
|
|
||||||
let (mut tx, mut rx) = mpsc::channel::<Multiaddr>(1);
|
let (mut tx, mut rx) = mpsc::channel::<Multiaddr>(1);
|
||||||
|
|
||||||
@ -127,10 +128,11 @@ fn max_failures() {
|
|||||||
.with_max_failures(max_failures.into());
|
.with_max_failures(max_failures.into());
|
||||||
|
|
||||||
let (peer1_id, trans) = mk_transport(muxer);
|
let (peer1_id, trans) = mk_transport(muxer);
|
||||||
let mut swarm1 = Swarm::new(trans, Behaviour::new(cfg.clone()), peer1_id);
|
let mut swarm1 =
|
||||||
|
Swarm::with_async_std_executor(trans, Behaviour::new(cfg.clone()), peer1_id);
|
||||||
|
|
||||||
let (peer2_id, trans) = mk_transport(muxer);
|
let (peer2_id, trans) = mk_transport(muxer);
|
||||||
let mut swarm2 = Swarm::new(trans, Behaviour::new(cfg), peer2_id);
|
let mut swarm2 = Swarm::with_async_std_executor(trans, Behaviour::new(cfg), peer2_id);
|
||||||
|
|
||||||
let (mut tx, mut rx) = mpsc::channel::<Multiaddr>(1);
|
let (mut tx, mut rx) = mpsc::channel::<Multiaddr>(1);
|
||||||
|
|
||||||
@ -197,10 +199,10 @@ fn max_failures() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn unsupported_doesnt_fail() {
|
fn unsupported_doesnt_fail() {
|
||||||
let (peer1_id, trans) = mk_transport(MuxerChoice::Mplex);
|
let (peer1_id, trans) = mk_transport(MuxerChoice::Mplex);
|
||||||
let mut swarm1 = Swarm::new(trans, keep_alive::Behaviour, peer1_id);
|
let mut swarm1 = Swarm::with_async_std_executor(trans, keep_alive::Behaviour, peer1_id);
|
||||||
|
|
||||||
let (peer2_id, trans) = mk_transport(MuxerChoice::Mplex);
|
let (peer2_id, trans) = mk_transport(MuxerChoice::Mplex);
|
||||||
let mut swarm2 = Swarm::new(trans, Behaviour::default(), peer2_id);
|
let mut swarm2 = Swarm::with_async_std_executor(trans, Behaviour::default(), peer2_id);
|
||||||
|
|
||||||
let (mut tx, mut rx) = mpsc::channel::<Multiaddr>(1);
|
let (mut tx, mut rx) = mpsc::channel::<Multiaddr>(1);
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
)),
|
)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut swarm = Swarm::new(transport, behaviour, local_peer_id);
|
let mut swarm = Swarm::without_executor(transport, behaviour, local_peer_id);
|
||||||
|
|
||||||
// Listen on all interfaces
|
// Listen on all interfaces
|
||||||
let listen_addr = Multiaddr::empty()
|
let listen_addr = Multiaddr::empty()
|
||||||
|
@ -291,7 +291,7 @@ fn build_relay() -> Swarm<Relay> {
|
|||||||
|
|
||||||
let transport = upgrade_transport(MemoryTransport::default().boxed(), local_public_key);
|
let transport = upgrade_transport(MemoryTransport::default().boxed(), local_public_key);
|
||||||
|
|
||||||
Swarm::new(
|
Swarm::with_threadpool_executor(
|
||||||
transport,
|
transport,
|
||||||
Relay {
|
Relay {
|
||||||
ping: ping::Behaviour::new(ping::Config::new()),
|
ping: ping::Behaviour::new(ping::Config::new()),
|
||||||
@ -318,7 +318,7 @@ fn build_client() -> Swarm<Client> {
|
|||||||
local_public_key,
|
local_public_key,
|
||||||
);
|
);
|
||||||
|
|
||||||
Swarm::new(
|
Swarm::with_threadpool_executor(
|
||||||
transport,
|
transport,
|
||||||
Client {
|
Client {
|
||||||
ping: ping::Behaviour::new(ping::Config::new()),
|
ping: ping::Behaviour::new(ping::Config::new()),
|
||||||
|
@ -25,7 +25,7 @@ use libp2p::multiaddr::Protocol;
|
|||||||
use libp2p::ping;
|
use libp2p::ping;
|
||||||
use libp2p::swarm::{keep_alive, SwarmEvent};
|
use libp2p::swarm::{keep_alive, SwarmEvent};
|
||||||
use libp2p::Swarm;
|
use libp2p::Swarm;
|
||||||
use libp2p::{development_transport, rendezvous, Multiaddr};
|
use libp2p::{rendezvous, tokio_development_transport, Multiaddr};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use void::Void;
|
use void::Void;
|
||||||
|
|
||||||
@ -41,8 +41,8 @@ async fn main() {
|
|||||||
.parse()
|
.parse()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut swarm = Swarm::new(
|
let mut swarm = Swarm::with_tokio_executor(
|
||||||
development_transport(identity.clone()).await.unwrap(),
|
tokio_development_transport(identity.clone()).unwrap(),
|
||||||
MyBehaviour {
|
MyBehaviour {
|
||||||
rendezvous: rendezvous::client::Behaviour::new(identity.clone()),
|
rendezvous: rendezvous::client::Behaviour::new(identity.clone()),
|
||||||
ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))),
|
ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))),
|
||||||
|
@ -24,7 +24,7 @@ use libp2p::core::PeerId;
|
|||||||
use libp2p::ping;
|
use libp2p::ping;
|
||||||
use libp2p::swarm::{NetworkBehaviour, Swarm, SwarmEvent};
|
use libp2p::swarm::{NetworkBehaviour, Swarm, SwarmEvent};
|
||||||
use libp2p::Multiaddr;
|
use libp2p::Multiaddr;
|
||||||
use libp2p::{development_transport, rendezvous};
|
use libp2p::{rendezvous, tokio_development_transport};
|
||||||
use libp2p_swarm::AddressScore;
|
use libp2p_swarm::AddressScore;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
@ -39,8 +39,8 @@ async fn main() {
|
|||||||
|
|
||||||
let identity = identity::Keypair::generate_ed25519();
|
let identity = identity::Keypair::generate_ed25519();
|
||||||
|
|
||||||
let mut swarm = Swarm::new(
|
let mut swarm = Swarm::with_tokio_executor(
|
||||||
development_transport(identity.clone()).await.unwrap(),
|
tokio_development_transport(identity.clone()).unwrap(),
|
||||||
MyBehaviour {
|
MyBehaviour {
|
||||||
rendezvous: rendezvous::client::Behaviour::new(identity.clone()),
|
rendezvous: rendezvous::client::Behaviour::new(identity.clone()),
|
||||||
ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))),
|
ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))),
|
||||||
|
@ -25,7 +25,7 @@ use libp2p::identify;
|
|||||||
use libp2p::ping;
|
use libp2p::ping;
|
||||||
use libp2p::swarm::{keep_alive, NetworkBehaviour, Swarm, SwarmEvent};
|
use libp2p::swarm::{keep_alive, NetworkBehaviour, Swarm, SwarmEvent};
|
||||||
use libp2p::Multiaddr;
|
use libp2p::Multiaddr;
|
||||||
use libp2p::{development_transport, rendezvous};
|
use libp2p::{rendezvous, tokio_development_transport};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use void::Void;
|
use void::Void;
|
||||||
|
|
||||||
@ -40,8 +40,8 @@ async fn main() {
|
|||||||
|
|
||||||
let identity = identity::Keypair::generate_ed25519();
|
let identity = identity::Keypair::generate_ed25519();
|
||||||
|
|
||||||
let mut swarm = Swarm::new(
|
let mut swarm = Swarm::with_tokio_executor(
|
||||||
development_transport(identity.clone()).await.unwrap(),
|
tokio_development_transport(identity.clone()).unwrap(),
|
||||||
MyBehaviour {
|
MyBehaviour {
|
||||||
identify: identify::Behaviour::new(identify::Config::new(
|
identify: identify::Behaviour::new(identify::Config::new(
|
||||||
"rendezvous-example/1.0.0".to_string(),
|
"rendezvous-example/1.0.0".to_string(),
|
||||||
|
@ -24,7 +24,7 @@ use libp2p::core::PeerId;
|
|||||||
use libp2p::identify;
|
use libp2p::identify;
|
||||||
use libp2p::ping;
|
use libp2p::ping;
|
||||||
use libp2p::swarm::{keep_alive, NetworkBehaviour, Swarm, SwarmEvent};
|
use libp2p::swarm::{keep_alive, NetworkBehaviour, Swarm, SwarmEvent};
|
||||||
use libp2p::{development_transport, rendezvous};
|
use libp2p::{rendezvous, tokio_development_transport};
|
||||||
use void::Void;
|
use void::Void;
|
||||||
|
|
||||||
/// Examples for the rendezvous protocol:
|
/// Examples for the rendezvous protocol:
|
||||||
@ -43,8 +43,8 @@ async fn main() {
|
|||||||
let key = identity::ed25519::SecretKey::from_bytes(bytes).expect("we always pass 32 bytes");
|
let key = identity::ed25519::SecretKey::from_bytes(bytes).expect("we always pass 32 bytes");
|
||||||
let identity = identity::Keypair::Ed25519(key.into());
|
let identity = identity::Keypair::Ed25519(key.into());
|
||||||
|
|
||||||
let mut swarm = Swarm::new(
|
let mut swarm = Swarm::with_tokio_executor(
|
||||||
development_transport(identity.clone()).await.unwrap(),
|
tokio_development_transport(identity.clone()).unwrap(),
|
||||||
MyBehaviour {
|
MyBehaviour {
|
||||||
identify: identify::Behaviour::new(identify::Config::new(
|
identify: identify::Behaviour::new(identify::Config::new(
|
||||||
"rendezvous-example/1.0.0".to_string(),
|
"rendezvous-example/1.0.0".to_string(),
|
||||||
|
@ -28,7 +28,7 @@ use libp2p::core::upgrade::SelectUpgrade;
|
|||||||
use libp2p::core::{identity, Multiaddr, PeerId, Transport};
|
use libp2p::core::{identity, Multiaddr, PeerId, Transport};
|
||||||
use libp2p::mplex::MplexConfig;
|
use libp2p::mplex::MplexConfig;
|
||||||
use libp2p::noise::NoiseAuthenticated;
|
use libp2p::noise::NoiseAuthenticated;
|
||||||
use libp2p::swarm::{AddressScore, NetworkBehaviour, Swarm, SwarmBuilder, SwarmEvent};
|
use libp2p::swarm::{AddressScore, NetworkBehaviour, Swarm, SwarmEvent};
|
||||||
use libp2p::yamux::YamuxConfig;
|
use libp2p::yamux::YamuxConfig;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@ -53,11 +53,7 @@ where
|
|||||||
.timeout(Duration::from_secs(5))
|
.timeout(Duration::from_secs(5))
|
||||||
.boxed();
|
.boxed();
|
||||||
|
|
||||||
SwarmBuilder::new(transport, behaviour_fn(peer_id, identity), peer_id)
|
Swarm::with_tokio_executor(transport, behaviour_fn(peer_id, identity), peer_id)
|
||||||
.executor(Box::new(|future| {
|
|
||||||
let _ = tokio::spawn(future);
|
|
||||||
}))
|
|
||||||
.build()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_rand_memory_address() -> Multiaddr {
|
fn get_rand_memory_address() -> Multiaddr {
|
||||||
|
@ -48,7 +48,7 @@ fn is_response_outbound() {
|
|||||||
|
|
||||||
let (peer1_id, trans) = mk_transport();
|
let (peer1_id, trans) = mk_transport();
|
||||||
let ping_proto1 = RequestResponse::new(PingCodec(), protocols, cfg);
|
let ping_proto1 = RequestResponse::new(PingCodec(), protocols, cfg);
|
||||||
let mut swarm1 = Swarm::new(trans, ping_proto1, peer1_id);
|
let mut swarm1 = Swarm::without_executor(trans, ping_proto1, peer1_id);
|
||||||
|
|
||||||
let request_id1 = swarm1
|
let request_id1 = swarm1
|
||||||
.behaviour_mut()
|
.behaviour_mut()
|
||||||
@ -87,11 +87,11 @@ fn ping_protocol() {
|
|||||||
|
|
||||||
let (peer1_id, trans) = mk_transport();
|
let (peer1_id, trans) = mk_transport();
|
||||||
let ping_proto1 = RequestResponse::new(PingCodec(), protocols.clone(), cfg.clone());
|
let ping_proto1 = RequestResponse::new(PingCodec(), protocols.clone(), cfg.clone());
|
||||||
let mut swarm1 = Swarm::new(trans, ping_proto1, peer1_id);
|
let mut swarm1 = Swarm::without_executor(trans, ping_proto1, peer1_id);
|
||||||
|
|
||||||
let (peer2_id, trans) = mk_transport();
|
let (peer2_id, trans) = mk_transport();
|
||||||
let ping_proto2 = RequestResponse::new(PingCodec(), protocols, cfg);
|
let ping_proto2 = RequestResponse::new(PingCodec(), protocols, cfg);
|
||||||
let mut swarm2 = Swarm::new(trans, ping_proto2, peer2_id);
|
let mut swarm2 = Swarm::without_executor(trans, ping_proto2, peer2_id);
|
||||||
|
|
||||||
let (mut tx, mut rx) = mpsc::channel::<Multiaddr>(1);
|
let (mut tx, mut rx) = mpsc::channel::<Multiaddr>(1);
|
||||||
|
|
||||||
@ -176,11 +176,11 @@ fn emits_inbound_connection_closed_failure() {
|
|||||||
|
|
||||||
let (peer1_id, trans) = mk_transport();
|
let (peer1_id, trans) = mk_transport();
|
||||||
let ping_proto1 = RequestResponse::new(PingCodec(), protocols.clone(), cfg.clone());
|
let ping_proto1 = RequestResponse::new(PingCodec(), protocols.clone(), cfg.clone());
|
||||||
let mut swarm1 = Swarm::new(trans, ping_proto1, peer1_id);
|
let mut swarm1 = Swarm::without_executor(trans, ping_proto1, peer1_id);
|
||||||
|
|
||||||
let (peer2_id, trans) = mk_transport();
|
let (peer2_id, trans) = mk_transport();
|
||||||
let ping_proto2 = RequestResponse::new(PingCodec(), protocols, cfg);
|
let ping_proto2 = RequestResponse::new(PingCodec(), protocols, cfg);
|
||||||
let mut swarm2 = Swarm::new(trans, ping_proto2, peer2_id);
|
let mut swarm2 = Swarm::without_executor(trans, ping_proto2, peer2_id);
|
||||||
|
|
||||||
let addr = "/ip4/127.0.0.1/tcp/0".parse().unwrap();
|
let addr = "/ip4/127.0.0.1/tcp/0".parse().unwrap();
|
||||||
swarm1.listen_on(addr).unwrap();
|
swarm1.listen_on(addr).unwrap();
|
||||||
@ -245,11 +245,11 @@ fn emits_inbound_connection_closed_if_channel_is_dropped() {
|
|||||||
|
|
||||||
let (peer1_id, trans) = mk_transport();
|
let (peer1_id, trans) = mk_transport();
|
||||||
let ping_proto1 = RequestResponse::new(PingCodec(), protocols.clone(), cfg.clone());
|
let ping_proto1 = RequestResponse::new(PingCodec(), protocols.clone(), cfg.clone());
|
||||||
let mut swarm1 = Swarm::new(trans, ping_proto1, peer1_id);
|
let mut swarm1 = Swarm::without_executor(trans, ping_proto1, peer1_id);
|
||||||
|
|
||||||
let (peer2_id, trans) = mk_transport();
|
let (peer2_id, trans) = mk_transport();
|
||||||
let ping_proto2 = RequestResponse::new(PingCodec(), protocols, cfg);
|
let ping_proto2 = RequestResponse::new(PingCodec(), protocols, cfg);
|
||||||
let mut swarm2 = Swarm::new(trans, ping_proto2, peer2_id);
|
let mut swarm2 = Swarm::without_executor(trans, ping_proto2, peer2_id);
|
||||||
|
|
||||||
let addr = "/ip4/127.0.0.1/tcp/0".parse().unwrap();
|
let addr = "/ip4/127.0.0.1/tcp/0".parse().unwrap();
|
||||||
swarm1.listen_on(addr).unwrap();
|
swarm1.listen_on(addr).unwrap();
|
||||||
|
@ -5,9 +5,70 @@
|
|||||||
- Export `NetworkBehaviour` derive as `libp2p_swarm::NetworkBehaviour`.
|
- Export `NetworkBehaviour` derive as `libp2p_swarm::NetworkBehaviour`.
|
||||||
This follows the convention of other popular libraries. `serde` for example exports the `Serialize` trait and macro as
|
This follows the convention of other popular libraries. `serde` for example exports the `Serialize` trait and macro as
|
||||||
`serde::Serialize`. See [PR 3055].
|
`serde::Serialize`. See [PR 3055].
|
||||||
|
|
||||||
- Feature-gate `NetworkBehaviour` macro behind `macros` feature flag. See [PR 3055].
|
- Feature-gate `NetworkBehaviour` macro behind `macros` feature flag. See [PR 3055].
|
||||||
|
|
||||||
|
- Make executor in Swarm constructor explicit. See [PR 3097].
|
||||||
|
|
||||||
|
Supported executors:
|
||||||
|
- Tokio
|
||||||
|
|
||||||
|
Previously
|
||||||
|
```rust
|
||||||
|
let swarm = SwarmBuilder::new(transport, behaviour, peer_id)
|
||||||
|
.executor(Box::new(|fut| {
|
||||||
|
tokio::spawn(fut);
|
||||||
|
}))
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
Now
|
||||||
|
```rust
|
||||||
|
let swarm = Swarm::with_tokio_executor(transport, behaviour, peer_id);
|
||||||
|
```
|
||||||
|
- Async Std
|
||||||
|
|
||||||
|
Previously
|
||||||
|
```rust
|
||||||
|
let swarm = SwarmBuilder::new(transport, behaviour, peer_id)
|
||||||
|
.executor(Box::new(|fut| {
|
||||||
|
async_std::task::spawn(fut);
|
||||||
|
}))
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
Now
|
||||||
|
```rust
|
||||||
|
let swarm = Swarm::with_async_std_executor(transport, behaviour, peer_id);
|
||||||
|
```
|
||||||
|
- ThreadPool (see [Issue 3107])
|
||||||
|
|
||||||
|
In most cases ThreadPool can be replaced by executors or spawning on the local task.
|
||||||
|
|
||||||
|
Previously
|
||||||
|
```rust
|
||||||
|
let swarm = Swarm::new(transport, behaviour, peer_id);
|
||||||
|
```
|
||||||
|
|
||||||
|
Now
|
||||||
|
```rust
|
||||||
|
let swarm = Swarm::with_threadpool_executor(transport, behaviour, peer_id);
|
||||||
|
```
|
||||||
|
- Without
|
||||||
|
|
||||||
|
Spawns the tasks on the current task, this may result in bad performance so try to use an executor where possible. Previously this was just a fallback when no executor was specified and constructing a `ThreadPool` failed.
|
||||||
|
|
||||||
|
New
|
||||||
|
```rust
|
||||||
|
let swarm = Swarm::without_executor(transport, behaviour, peer_id);
|
||||||
|
```
|
||||||
|
|
||||||
|
Deprecated APIs:
|
||||||
|
- `Swarm::new`
|
||||||
|
- `SwarmBuilder::new`
|
||||||
|
- `SwarmBuilder::executor`
|
||||||
|
|
||||||
[PR 3055]: https://github.com/libp2p/rust-libp2p/pull/3055
|
[PR 3055]: https://github.com/libp2p/rust-libp2p/pull/3055
|
||||||
|
[PR 3097]: https://github.com/libp2p/rust-libp2p/pull/3097
|
||||||
|
[Issue 3107]: https://github.com/libp2p/rust-libp2p/issues/3107
|
||||||
|
|
||||||
# 0.40.1
|
# 0.40.1
|
||||||
|
|
||||||
|
@ -24,9 +24,13 @@ rand = "0.8"
|
|||||||
smallvec = "1.6.1"
|
smallvec = "1.6.1"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
void = "1"
|
void = "1"
|
||||||
|
tokio = { version = "1.15", features = ["rt"], optional = true }
|
||||||
|
async-std = { version = "1.6.2", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
macros = ["dep:libp2p-swarm-derive"]
|
macros = ["dep:libp2p-swarm-derive"]
|
||||||
|
tokio = ["dep:tokio"]
|
||||||
|
async-std = ["dep:async-std"]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
async-std = { version = "1.6.2", features = ["attributes"] }
|
async-std = { version = "1.6.2", features = ["attributes"] }
|
||||||
|
@ -54,10 +54,34 @@ use void::Void;
|
|||||||
mod concurrent_dial;
|
mod concurrent_dial;
|
||||||
mod task;
|
mod task;
|
||||||
|
|
||||||
|
enum ExecSwitch {
|
||||||
|
Executor(Box<dyn Executor + Send>),
|
||||||
|
LocalSpawn(FuturesUnordered<Pin<Box<dyn Future<Output = ()> + Send>>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExecSwitch {
|
||||||
|
fn advance_local(&mut self, cx: &mut Context) {
|
||||||
|
match self {
|
||||||
|
ExecSwitch::Executor(_) => {}
|
||||||
|
ExecSwitch::LocalSpawn(local) => {
|
||||||
|
while let Poll::Ready(Some(())) = local.poll_next_unpin(cx) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spawn(&mut self, task: BoxFuture<'static, ()>) {
|
||||||
|
match self {
|
||||||
|
Self::Executor(executor) => executor.exec(task),
|
||||||
|
Self::LocalSpawn(local) => local.push(task),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A connection `Pool` manages a set of connections for each peer.
|
/// A connection `Pool` manages a set of connections for each peer.
|
||||||
pub struct Pool<THandler: IntoConnectionHandler, TTrans>
|
pub struct Pool<THandler, TTrans>
|
||||||
where
|
where
|
||||||
TTrans: Transport,
|
TTrans: Transport,
|
||||||
|
THandler: IntoConnectionHandler,
|
||||||
{
|
{
|
||||||
local_id: PeerId,
|
local_id: PeerId,
|
||||||
|
|
||||||
@ -93,14 +117,9 @@ where
|
|||||||
/// See [`Connection::max_negotiating_inbound_streams`].
|
/// See [`Connection::max_negotiating_inbound_streams`].
|
||||||
max_negotiating_inbound_streams: usize,
|
max_negotiating_inbound_streams: usize,
|
||||||
|
|
||||||
/// The executor to use for running the background tasks. If `None`,
|
/// The executor to use for running connection tasks. Can either be a global executor
|
||||||
/// the tasks are kept in `local_spawns` instead and polled on the
|
/// or a local queue.
|
||||||
/// current thread when the [`Pool`] is polled for new events.
|
executor: ExecSwitch,
|
||||||
executor: Option<Box<dyn Executor + Send>>,
|
|
||||||
|
|
||||||
/// If no `executor` is configured, tasks are kept in this set and
|
|
||||||
/// polled on the current thread when the [`Pool`] is polled for new events.
|
|
||||||
local_spawns: FuturesUnordered<Pin<Box<dyn Future<Output = ()> + Send>>>,
|
|
||||||
|
|
||||||
/// Sender distributed to pending tasks for reporting events back
|
/// Sender distributed to pending tasks for reporting events back
|
||||||
/// to the pool.
|
/// to the pool.
|
||||||
@ -299,6 +318,10 @@ where
|
|||||||
mpsc::channel(config.task_event_buffer_size);
|
mpsc::channel(config.task_event_buffer_size);
|
||||||
let (established_connection_events_tx, established_connection_events_rx) =
|
let (established_connection_events_tx, established_connection_events_rx) =
|
||||||
mpsc::channel(config.task_event_buffer_size);
|
mpsc::channel(config.task_event_buffer_size);
|
||||||
|
let executor = match config.executor {
|
||||||
|
Some(exec) => ExecSwitch::Executor(exec),
|
||||||
|
None => ExecSwitch::LocalSpawn(Default::default()),
|
||||||
|
};
|
||||||
Pool {
|
Pool {
|
||||||
local_id,
|
local_id,
|
||||||
counters: ConnectionCounters::new(limits),
|
counters: ConnectionCounters::new(limits),
|
||||||
@ -309,8 +332,7 @@ where
|
|||||||
dial_concurrency_factor: config.dial_concurrency_factor,
|
dial_concurrency_factor: config.dial_concurrency_factor,
|
||||||
substream_upgrade_protocol_override: config.substream_upgrade_protocol_override,
|
substream_upgrade_protocol_override: config.substream_upgrade_protocol_override,
|
||||||
max_negotiating_inbound_streams: config.max_negotiating_inbound_streams,
|
max_negotiating_inbound_streams: config.max_negotiating_inbound_streams,
|
||||||
executor: config.executor,
|
executor,
|
||||||
local_spawns: FuturesUnordered::new(),
|
|
||||||
pending_connection_events_tx,
|
pending_connection_events_tx,
|
||||||
pending_connection_events_rx,
|
pending_connection_events_rx,
|
||||||
established_connection_events_tx,
|
established_connection_events_tx,
|
||||||
@ -399,11 +421,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn spawn(&mut self, task: BoxFuture<'static, ()>) {
|
fn spawn(&mut self, task: BoxFuture<'static, ()>) {
|
||||||
if let Some(executor) = &mut self.executor {
|
self.executor.spawn(task)
|
||||||
executor.exec(task);
|
|
||||||
} else {
|
|
||||||
self.local_spawns.push(task);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -820,8 +838,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance the tasks in `local_spawns`.
|
self.executor.advance_local(cx);
|
||||||
while let Poll::Ready(Some(())) = self.local_spawns.poll_next_unpin(cx) {}
|
|
||||||
|
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
@ -1073,34 +1090,21 @@ pub struct PoolConfig {
|
|||||||
max_negotiating_inbound_streams: usize,
|
max_negotiating_inbound_streams: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PoolConfig {
|
impl PoolConfig {
|
||||||
fn default() -> Self {
|
pub fn new(executor: Option<Box<dyn Executor + Send>>) -> Self {
|
||||||
PoolConfig {
|
Self {
|
||||||
executor: None,
|
executor,
|
||||||
task_event_buffer_size: 32,
|
task_command_buffer_size: 32,
|
||||||
task_command_buffer_size: 7,
|
task_event_buffer_size: 7,
|
||||||
// Set to a default of 8 based on frequency of dialer connections
|
|
||||||
dial_concurrency_factor: NonZeroU8::new(8).expect("8 > 0"),
|
dial_concurrency_factor: NonZeroU8::new(8).expect("8 > 0"),
|
||||||
substream_upgrade_protocol_override: None,
|
substream_upgrade_protocol_override: None,
|
||||||
max_negotiating_inbound_streams: 128,
|
max_negotiating_inbound_streams: 128,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl PoolConfig {
|
|
||||||
/// Configures the executor to use for spawning connection background tasks.
|
/// Configures the executor to use for spawning connection background tasks.
|
||||||
pub fn with_executor(mut self, e: Box<dyn Executor + Send>) -> Self {
|
pub fn with_executor(mut self, executor: Box<dyn Executor + Send>) -> Self {
|
||||||
self.executor = Some(e);
|
self.executor = Some(executor);
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the executor to use for spawning connection background tasks,
|
|
||||||
/// only if no executor has already been configured.
|
|
||||||
pub fn or_else_with_executor<F>(mut self, f: F) -> Self
|
|
||||||
where
|
|
||||||
F: FnOnce() -> Option<Box<dyn Executor + Send>>,
|
|
||||||
{
|
|
||||||
self.executor = self.executor.or_else(f);
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1174,13 +1178,4 @@ mod tests {
|
|||||||
impl Executor for Dummy {
|
impl Executor for Dummy {
|
||||||
fn exec(&self, _: Pin<Box<dyn Future<Output = ()> + Send>>) {}
|
fn exec(&self, _: Pin<Box<dyn Future<Output = ()> + Send>>) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn set_executor() {
|
|
||||||
PoolConfig::default()
|
|
||||||
.with_executor(Box::new(Dummy))
|
|
||||||
.with_executor(Box::new(|f| {
|
|
||||||
async_std::task::spawn(f);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
166
swarm/src/lib.rs
166
swarm/src/lib.rs
@ -64,6 +64,7 @@ mod upgrade;
|
|||||||
pub mod behaviour;
|
pub mod behaviour;
|
||||||
pub mod dial_opts;
|
pub mod dial_opts;
|
||||||
pub mod dummy;
|
pub mod dummy;
|
||||||
|
mod executor;
|
||||||
pub mod handler;
|
pub mod handler;
|
||||||
pub mod keep_alive;
|
pub mod keep_alive;
|
||||||
|
|
||||||
@ -94,6 +95,7 @@ pub use connection::{
|
|||||||
ConnectionError, ConnectionLimit, PendingConnectionError, PendingInboundConnectionError,
|
ConnectionError, ConnectionLimit, PendingConnectionError, PendingInboundConnectionError,
|
||||||
PendingOutboundConnectionError,
|
PendingOutboundConnectionError,
|
||||||
};
|
};
|
||||||
|
pub use executor::Executor;
|
||||||
pub use handler::{
|
pub use handler::{
|
||||||
ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerSelect, ConnectionHandlerUpgrErr,
|
ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerSelect, ConnectionHandlerUpgrErr,
|
||||||
IntoConnectionHandler, IntoConnectionHandlerSelect, KeepAlive, OneShotHandler,
|
IntoConnectionHandler, IntoConnectionHandlerSelect, KeepAlive, OneShotHandler,
|
||||||
@ -117,7 +119,7 @@ use libp2p_core::{
|
|||||||
muxing::StreamMuxerBox,
|
muxing::StreamMuxerBox,
|
||||||
transport::{self, ListenerId, TransportError, TransportEvent},
|
transport::{self, ListenerId, TransportError, TransportEvent},
|
||||||
upgrade::ProtocolName,
|
upgrade::ProtocolName,
|
||||||
Endpoint, Executor, Multiaddr, Negotiated, PeerId, Transport,
|
Endpoint, Multiaddr, Negotiated, PeerId, Transport,
|
||||||
};
|
};
|
||||||
use registry::{AddressIntoIter, Addresses};
|
use registry::{AddressIntoIter, Addresses};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
@ -328,12 +330,89 @@ where
|
|||||||
TBehaviour: NetworkBehaviour,
|
TBehaviour: NetworkBehaviour,
|
||||||
{
|
{
|
||||||
/// Builds a new `Swarm`.
|
/// Builds a new `Swarm`.
|
||||||
|
#[deprecated(
|
||||||
|
since = "0.41.0",
|
||||||
|
note = "This constructor is considered ambiguous regarding the executor. Use one of the new, executor-specific constructors or `Swarm::with_threadpool_executor` for the same behaviour."
|
||||||
|
)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
transport: transport::Boxed<(PeerId, StreamMuxerBox)>,
|
transport: transport::Boxed<(PeerId, StreamMuxerBox)>,
|
||||||
behaviour: TBehaviour,
|
behaviour: TBehaviour,
|
||||||
local_peer_id: PeerId,
|
local_peer_id: PeerId,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
SwarmBuilder::new(transport, behaviour, local_peer_id).build()
|
Self::with_threadpool_executor(transport, behaviour, local_peer_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Builds a new `Swarm` with a provided executor.
|
||||||
|
pub fn with_executor(
|
||||||
|
transport: transport::Boxed<(PeerId, StreamMuxerBox)>,
|
||||||
|
behaviour: TBehaviour,
|
||||||
|
local_peer_id: PeerId,
|
||||||
|
executor: impl Executor + Send + 'static,
|
||||||
|
) -> Self {
|
||||||
|
SwarmBuilder::with_executor(transport, behaviour, local_peer_id, executor).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Builds a new `Swarm` with a tokio executor.
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
|
pub fn with_tokio_executor(
|
||||||
|
transport: transport::Boxed<(PeerId, StreamMuxerBox)>,
|
||||||
|
behaviour: TBehaviour,
|
||||||
|
local_peer_id: PeerId,
|
||||||
|
) -> Self {
|
||||||
|
Self::with_executor(
|
||||||
|
transport,
|
||||||
|
behaviour,
|
||||||
|
local_peer_id,
|
||||||
|
crate::executor::TokioExecutor,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Builds a new `Swarm` with an async-std executor.
|
||||||
|
#[cfg(feature = "async-std")]
|
||||||
|
pub fn with_async_std_executor(
|
||||||
|
transport: transport::Boxed<(PeerId, StreamMuxerBox)>,
|
||||||
|
behaviour: TBehaviour,
|
||||||
|
local_peer_id: PeerId,
|
||||||
|
) -> Self {
|
||||||
|
Self::with_executor(
|
||||||
|
transport,
|
||||||
|
behaviour,
|
||||||
|
local_peer_id,
|
||||||
|
crate::executor::AsyncStdExecutor,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Builds a new `Swarm` with a threadpool executor.
|
||||||
|
pub fn with_threadpool_executor(
|
||||||
|
transport: transport::Boxed<(PeerId, StreamMuxerBox)>,
|
||||||
|
behaviour: TBehaviour,
|
||||||
|
local_peer_id: PeerId,
|
||||||
|
) -> Self {
|
||||||
|
let builder = match ThreadPoolBuilder::new()
|
||||||
|
.name_prefix("libp2p-swarm-task-")
|
||||||
|
.create()
|
||||||
|
{
|
||||||
|
Ok(tp) => SwarmBuilder::with_executor(transport, behaviour, local_peer_id, tp),
|
||||||
|
Err(err) => {
|
||||||
|
log::warn!("Failed to create executor thread pool: {:?}", err);
|
||||||
|
SwarmBuilder::without_executor(transport, behaviour, local_peer_id)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
builder.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Builds a new `Swarm` without an executor, instead using the current task.
|
||||||
|
///
|
||||||
|
/// ## ⚠️ Performance warning
|
||||||
|
/// All connections will be polled on the current task, thus quite bad performance
|
||||||
|
/// characteristics should be expected. Whenever possible use an executor and
|
||||||
|
/// [`Swarm::with_executor`].
|
||||||
|
pub fn without_executor(
|
||||||
|
transport: transport::Boxed<(PeerId, StreamMuxerBox)>,
|
||||||
|
behaviour: TBehaviour,
|
||||||
|
local_peer_id: PeerId,
|
||||||
|
) -> Self {
|
||||||
|
SwarmBuilder::without_executor(transport, behaviour, local_peer_id).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns information about the connections underlying the [`Swarm`].
|
/// Returns information about the connections underlying the [`Swarm`].
|
||||||
@ -1294,16 +1373,67 @@ where
|
|||||||
/// Creates a new `SwarmBuilder` from the given transport, behaviour and
|
/// Creates a new `SwarmBuilder` from the given transport, behaviour and
|
||||||
/// local peer ID. The `Swarm` with its underlying `Network` is obtained
|
/// local peer ID. The `Swarm` with its underlying `Network` is obtained
|
||||||
/// via [`SwarmBuilder::build`].
|
/// via [`SwarmBuilder::build`].
|
||||||
|
#[deprecated(
|
||||||
|
since = "0.41.0",
|
||||||
|
note = "Use `SwarmBuilder::with_executor` or `SwarmBuilder::without_executor` instead."
|
||||||
|
)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
transport: transport::Boxed<(PeerId, StreamMuxerBox)>,
|
transport: transport::Boxed<(PeerId, StreamMuxerBox)>,
|
||||||
behaviour: TBehaviour,
|
behaviour: TBehaviour,
|
||||||
local_peer_id: PeerId,
|
local_peer_id: PeerId,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let executor: Option<Box<dyn Executor + Send>> = match ThreadPoolBuilder::new()
|
||||||
|
.name_prefix("libp2p-swarm-task-")
|
||||||
|
.create()
|
||||||
|
.ok()
|
||||||
|
{
|
||||||
|
Some(tp) => Some(Box::new(tp)),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
SwarmBuilder {
|
SwarmBuilder {
|
||||||
local_peer_id,
|
local_peer_id,
|
||||||
transport,
|
transport,
|
||||||
behaviour,
|
behaviour,
|
||||||
pool_config: Default::default(),
|
pool_config: PoolConfig::new(executor),
|
||||||
|
connection_limits: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new [`SwarmBuilder`] from the given transport, behaviour, local peer ID and
|
||||||
|
/// executor. The `Swarm` with its underlying `Network` is obtained via
|
||||||
|
/// [`SwarmBuilder::build`].
|
||||||
|
pub fn with_executor(
|
||||||
|
transport: transport::Boxed<(PeerId, StreamMuxerBox)>,
|
||||||
|
behaviour: TBehaviour,
|
||||||
|
local_peer_id: PeerId,
|
||||||
|
executor: impl Executor + Send + 'static,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
local_peer_id,
|
||||||
|
transport,
|
||||||
|
behaviour,
|
||||||
|
pool_config: PoolConfig::new(Some(Box::new(executor))),
|
||||||
|
connection_limits: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new [`SwarmBuilder`] from the given transport, behaviour and local peer ID. The
|
||||||
|
/// `Swarm` with its underlying `Network` is obtained via [`SwarmBuilder::build`].
|
||||||
|
///
|
||||||
|
/// ## ⚠️ Performance warning
|
||||||
|
/// All connections will be polled on the current task, thus quite bad performance
|
||||||
|
/// characteristics should be expected. Whenever possible use an executor and
|
||||||
|
/// [`SwarmBuilder::with_executor`].
|
||||||
|
pub fn without_executor(
|
||||||
|
transport: transport::Boxed<(PeerId, StreamMuxerBox)>,
|
||||||
|
behaviour: TBehaviour,
|
||||||
|
local_peer_id: PeerId,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
local_peer_id,
|
||||||
|
transport,
|
||||||
|
behaviour,
|
||||||
|
pool_config: PoolConfig::new(None),
|
||||||
connection_limits: Default::default(),
|
connection_limits: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1313,8 +1443,9 @@ where
|
|||||||
/// By default, unless another executor has been configured,
|
/// By default, unless another executor has been configured,
|
||||||
/// [`SwarmBuilder::build`] will try to set up a
|
/// [`SwarmBuilder::build`] will try to set up a
|
||||||
/// [`ThreadPool`](futures::executor::ThreadPool).
|
/// [`ThreadPool`](futures::executor::ThreadPool).
|
||||||
pub fn executor(mut self, e: Box<dyn Executor + Send>) -> Self {
|
#[deprecated(since = "0.41.0", note = "Use `SwarmBuilder::with_executor` instead.")]
|
||||||
self.pool_config = self.pool_config.with_executor(e);
|
pub fn executor(mut self, executor: Box<dyn Executor + Send>) -> Self {
|
||||||
|
self.pool_config = self.pool_config.with_executor(executor);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1412,25 +1543,10 @@ where
|
|||||||
.map(|info| info.protocol_name().to_vec())
|
.map(|info| info.protocol_name().to_vec())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// If no executor has been explicitly configured, try to set up a thread pool.
|
|
||||||
let pool_config =
|
|
||||||
self.pool_config.or_else_with_executor(|| {
|
|
||||||
match ThreadPoolBuilder::new()
|
|
||||||
.name_prefix("libp2p-swarm-task-")
|
|
||||||
.create()
|
|
||||||
{
|
|
||||||
Ok(tp) => Some(Box::new(move |f| tp.spawn_ok(f))),
|
|
||||||
Err(err) => {
|
|
||||||
log::warn!("Failed to create executor thread pool: {:?}", err);
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Swarm {
|
Swarm {
|
||||||
local_peer_id: self.local_peer_id,
|
local_peer_id: self.local_peer_id,
|
||||||
transport: self.transport,
|
transport: self.transport,
|
||||||
pool: Pool::new(self.local_peer_id, pool_config, self.connection_limits),
|
pool: Pool::new(self.local_peer_id, self.pool_config, self.connection_limits),
|
||||||
behaviour: self.behaviour,
|
behaviour: self.behaviour,
|
||||||
supported_protocols,
|
supported_protocols,
|
||||||
listened_addrs: HashMap::new(),
|
listened_addrs: HashMap::new(),
|
||||||
@ -1586,6 +1702,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::test::{CallTraceBehaviour, MockBehaviour};
|
use crate::test::{CallTraceBehaviour, MockBehaviour};
|
||||||
use futures::executor::block_on;
|
use futures::executor::block_on;
|
||||||
|
use futures::executor::ThreadPool;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
use futures::future::Either;
|
use futures::future::Either;
|
||||||
use futures::{executor, future, ready};
|
use futures::{executor, future, ready};
|
||||||
@ -1622,7 +1739,12 @@ mod tests {
|
|||||||
.multiplex(yamux::YamuxConfig::default())
|
.multiplex(yamux::YamuxConfig::default())
|
||||||
.boxed();
|
.boxed();
|
||||||
let behaviour = CallTraceBehaviour::new(MockBehaviour::new(handler_proto));
|
let behaviour = CallTraceBehaviour::new(MockBehaviour::new(handler_proto));
|
||||||
SwarmBuilder::new(transport, behaviour, local_public_key.into())
|
match ThreadPool::new().ok() {
|
||||||
|
Some(tp) => {
|
||||||
|
SwarmBuilder::with_executor(transport, behaviour, local_public_key.into(), tp)
|
||||||
|
}
|
||||||
|
None => SwarmBuilder::without_executor(transport, behaviour, local_public_key.into()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn swarms_connected<TBehaviour>(
|
fn swarms_connected<TBehaviour>(
|
||||||
|
@ -65,7 +65,7 @@ fn make_swarm() -> Swarm<keep_alive::Behaviour> {
|
|||||||
.multiplex(libp2p::yamux::YamuxConfig::default())
|
.multiplex(libp2p::yamux::YamuxConfig::default())
|
||||||
.boxed();
|
.boxed();
|
||||||
|
|
||||||
Swarm::new(
|
Swarm::without_executor(
|
||||||
transport,
|
transport,
|
||||||
keep_alive::Behaviour,
|
keep_alive::Behaviour,
|
||||||
identity.public().to_peer_id(),
|
identity.public().to_peer_id(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user