mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-27 16:51:34 +00:00
Add back simple, optional keep-alive to libp2p-ping. (#1088)
This is now a very simple option serving multiple purposes: * It allows for stable (integration) tests involving a Swarm, which are otherwise subject to race conditions due to the connection being allowed to terminate at any time with `KeepAlive::No` (which remains the default). * It makes for a more entertaining ping example which continuously sends pings. * Maybe someone wants to use the ping protocol for application-layer connection keep-alive after all.
This commit is contained in:
@ -39,7 +39,7 @@
|
||||
//! and begin pinging each other.
|
||||
|
||||
use futures::{prelude::*, future};
|
||||
use libp2p::{ identity, PeerId, ping::Ping, Swarm };
|
||||
use libp2p::{ identity, PeerId, ping::{Ping, PingConfig}, Swarm };
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
@ -54,7 +54,11 @@ fn main() {
|
||||
let transport = libp2p::build_development_transport(id_keys);
|
||||
|
||||
// Create a ping network behaviour.
|
||||
let behaviour = Ping::default();
|
||||
//
|
||||
// For illustrative purposes, the ping protocol is configured to
|
||||
// keep the connection alive, so a continuous sequence of pings
|
||||
// can be observed.
|
||||
let behaviour = Ping::new(PingConfig::new().with_keep_alive(true));
|
||||
|
||||
// Create a Swarm that establishes connections through the given transport
|
||||
// and applies the ping behaviour on each connection.
|
||||
|
@ -45,6 +45,9 @@ pub struct PingConfig {
|
||||
/// connection is deemed unhealthy, indicating to the `Swarm` that it
|
||||
/// should be closed.
|
||||
max_failures: NonZeroU32,
|
||||
/// Whether the connection should generally be kept alive unless
|
||||
/// `max_failures` occur.
|
||||
keep_alive: bool,
|
||||
}
|
||||
|
||||
impl PingConfig {
|
||||
@ -53,6 +56,7 @@ impl PingConfig {
|
||||
/// * [`PingConfig::with_interval`] 15s
|
||||
/// * [`PingConfig::with_timeout`] 20s
|
||||
/// * [`PingConfig::with_max_failures`] 1
|
||||
/// * [`PingConfig::with_keep_alive`] false
|
||||
///
|
||||
/// These settings have the following effect:
|
||||
///
|
||||
@ -61,11 +65,15 @@ impl PingConfig {
|
||||
/// be successful.
|
||||
/// * A single ping failure is sufficient for the connection to be subject
|
||||
/// to being closed.
|
||||
/// * The connection may be closed at any time as far as the ping protocol
|
||||
/// is concerned, i.e. the ping protocol itself does not keep the
|
||||
/// connection alive.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
timeout: Duration::from_secs(20),
|
||||
interval: Duration::from_secs(15),
|
||||
max_failures: NonZeroU32::new(1).expect("1 != 0"),
|
||||
keep_alive: false
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,6 +95,21 @@ impl PingConfig {
|
||||
self.max_failures = n;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets whether the ping protocol itself should keep the connection alive,
|
||||
/// apart from the maximum allowed failures.
|
||||
///
|
||||
/// By default, the ping protocol itself allows the connection to be closed
|
||||
/// at any time, i.e. in the absence of ping failures the connection lifetime
|
||||
/// is determined by other protocol handlers.
|
||||
///
|
||||
/// If the maximum number of allowed ping failures is reached, the
|
||||
/// connection is always terminated as a result of [`PingHandler::poll`]
|
||||
/// returning an error, regardless of the keep-alive setting.
|
||||
pub fn with_keep_alive(mut self, b: bool) -> Self {
|
||||
self.keep_alive = b;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// The result of an inbound or outbound ping.
|
||||
@ -198,11 +221,11 @@ where
|
||||
}
|
||||
|
||||
fn connection_keep_alive(&self) -> KeepAlive {
|
||||
// Returning `Now` indicates that, as far as this handler is concerned,
|
||||
// the connection may be closed. I.e. the ping handler does not keep
|
||||
// the connection alive, it merely adds another condition (failed pings)
|
||||
// for terminating it.
|
||||
KeepAlive::No
|
||||
if self.config.keep_alive {
|
||||
KeepAlive::Yes
|
||||
} else {
|
||||
KeepAlive::No
|
||||
}
|
||||
}
|
||||
|
||||
fn poll(&mut self) -> Poll<ProtocolsHandlerEvent<protocol::Ping, (), PingResult>, Self::Error> {
|
||||
|
@ -39,11 +39,13 @@ use tokio::runtime::Runtime;
|
||||
|
||||
#[test]
|
||||
fn ping() {
|
||||
let cfg = PingConfig::new().with_keep_alive(true);
|
||||
|
||||
let (peer1_id, trans) = mk_transport();
|
||||
let mut swarm1 = Swarm::new(trans, Ping::default(), peer1_id.clone());
|
||||
let mut swarm1 = Swarm::new(trans, Ping::new(cfg.clone()), peer1_id.clone());
|
||||
|
||||
let (peer2_id, trans) = mk_transport();
|
||||
let mut swarm2 = Swarm::new(trans, Ping::default(), peer2_id.clone());
|
||||
let mut swarm2 = Swarm::new(trans, Ping::new(cfg), peer2_id.clone());
|
||||
|
||||
let (tx, rx) = sync_channel::<Multiaddr>(1);
|
||||
|
||||
|
Reference in New Issue
Block a user