Skip to content

Commit c52a2fc

Browse files
feat(swarm): allow configuration to idle connection timeout
Previously, a connection would be shut down immediately as soon as its `ConnectionHandler` reports `KeepAlive::No`. As we have gained experience with libp2p, it turned out that this isn't ideal. For one, tests often need to keep connections alive longer than the configured protocols require. Plus, some usecases require connections to be kept alive in general. Both of these needs are currently served by the `keep_alive::Behaviour`. That one does essentially nothing other than statically returning `KeepAlive::Yes` from its `ConnectionHandler`. It makes much more sense to deprecate `keep_alive::Behaviour` and instead allow users to globally configure an `idle_conncetion_timeout` on the `Swarm`. This timeout comes into effect once a `ConnectionHandler` reports `KeepAlive::No`. To start with, this timeout is 0. Together with #3844, this will allow us to move towards a much more aggressive closing of idle connections, together with a more ergonomic way of opting out of this behaviour. Fixes #4121. Pull-Request: #4161.
1 parent ff92ba0 commit c52a2fc

File tree

22 files changed

+378
-331
lines changed

22 files changed

+378
-331
lines changed

examples/browser-webrtc/src/main.rs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ use libp2p::{
1313
identity,
1414
multiaddr::{Multiaddr, Protocol},
1515
ping,
16-
swarm::{keep_alive, NetworkBehaviour, SwarmBuilder, SwarmEvent},
16+
swarm::{SwarmBuilder, SwarmEvent},
1717
};
1818
use libp2p_webrtc as webrtc;
1919
use rand::thread_rng;
2020
use std::net::{Ipv4Addr, SocketAddr};
21+
use std::time::Duration;
2122
use tower_http::cors::{Any, CorsLayer};
2223

2324
#[tokio::main]
@@ -36,12 +37,10 @@ async fn main() -> anyhow::Result<()> {
3637
.map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn)))
3738
.boxed();
3839

39-
let behaviour = Behaviour {
40-
ping: ping::Behaviour::new(ping::Config::new()),
41-
keep_alive: keep_alive::Behaviour,
42-
};
43-
44-
let mut swarm = SwarmBuilder::with_tokio_executor(transport, behaviour, local_peer_id).build();
40+
let mut swarm =
41+
SwarmBuilder::with_tokio_executor(transport, ping::Behaviour::default(), local_peer_id)
42+
.idle_connection_timeout(Duration::from_secs(30)) // Allows us to observe the pings.
43+
.build();
4544

4645
let address_webrtc = Multiaddr::from(Ipv4Addr::UNSPECIFIED)
4746
.with(Protocol::Udp(0))
@@ -84,12 +83,6 @@ async fn main() -> anyhow::Result<()> {
8483
Ok(())
8584
}
8685

87-
#[derive(NetworkBehaviour)]
88-
struct Behaviour {
89-
ping: ping::Behaviour,
90-
keep_alive: keep_alive::Behaviour,
91-
}
92-
9386
#[derive(rust_embed::RustEmbed)]
9487
#[folder = "$CARGO_MANIFEST_DIR/static"]
9588
struct StaticFiles;

examples/metrics/src/main.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@ use futures::stream::StreamExt;
2626
use libp2p::core::{upgrade::Version, Multiaddr, Transport};
2727
use libp2p::identity::PeerId;
2828
use libp2p::metrics::{Metrics, Recorder};
29-
use libp2p::swarm::{keep_alive, NetworkBehaviour, SwarmBuilder, SwarmEvent};
29+
use libp2p::swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent};
3030
use libp2p::{identify, identity, noise, ping, tcp, yamux};
3131
use log::info;
3232
use prometheus_client::registry::Registry;
3333
use std::error::Error;
3434
use std::thread;
35+
use std::time::Duration;
3536

3637
mod http_service;
3738

@@ -51,6 +52,7 @@ fn main() -> Result<(), Box<dyn Error>> {
5152
Behaviour::new(local_pub_key),
5253
local_peer_id,
5354
)
55+
.idle_connection_timeout(Duration::from_secs(60))
5456
.build();
5557

5658
swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;
@@ -87,13 +89,9 @@ fn main() -> Result<(), Box<dyn Error>> {
8789
}
8890

8991
/// Our network behaviour.
90-
///
91-
/// For illustrative purposes, this includes the [`keep_alive::Behaviour`]) behaviour so the ping actually happen
92-
/// and can be observed via the metrics.
9392
#[derive(NetworkBehaviour)]
9493
struct Behaviour {
9594
identify: identify::Behaviour,
96-
keep_alive: keep_alive::Behaviour,
9795
ping: ping::Behaviour,
9896
}
9997

@@ -105,7 +103,6 @@ impl Behaviour {
105103
"/ipfs/0.1.0".into(),
106104
local_pub_key,
107105
)),
108-
keep_alive: keep_alive::Behaviour,
109106
}
110107
}
111108
}

examples/ping-example/src/main.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ use futures::prelude::*;
2424
use libp2p::core::upgrade::Version;
2525
use libp2p::{
2626
identity, noise, ping,
27-
swarm::{keep_alive, NetworkBehaviour, SwarmBuilder, SwarmEvent},
27+
swarm::{SwarmBuilder, SwarmEvent},
2828
tcp, yamux, Multiaddr, PeerId, Transport,
2929
};
3030
use std::error::Error;
31+
use std::time::Duration;
3132

3233
#[async_std::main]
3334
async fn main() -> Result<(), Box<dyn Error>> {
@@ -42,7 +43,8 @@ async fn main() -> Result<(), Box<dyn Error>> {
4243
.boxed();
4344

4445
let mut swarm =
45-
SwarmBuilder::with_async_std_executor(transport, Behaviour::default(), local_peer_id)
46+
SwarmBuilder::with_async_std_executor(transport, ping::Behaviour::default(), local_peer_id)
47+
.idle_connection_timeout(Duration::from_secs(60)) // For illustrative purposes, keep idle connections alive for a minute so we can observe a few pings.
4648
.build();
4749

4850
// Tell the swarm to listen on all interfaces and a random, OS-assigned
@@ -65,13 +67,3 @@ async fn main() -> Result<(), Box<dyn Error>> {
6567
}
6668
}
6769
}
68-
69-
/// Our network behaviour.
70-
///
71-
/// For illustrative purposes, this includes the [`KeepAlive`](keep_alive::Behaviour) behaviour so a continuous sequence of
72-
/// pings can be observed.
73-
#[derive(NetworkBehaviour, Default)]
74-
struct Behaviour {
75-
keep_alive: keep_alive::Behaviour,
76-
ping: ping::Behaviour,
77-
}

examples/rendezvous/src/bin/rzv-discover.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use libp2p::{
2424
identity,
2525
multiaddr::Protocol,
2626
noise, ping, rendezvous,
27-
swarm::{keep_alive, NetworkBehaviour, SwarmBuilder, SwarmEvent},
27+
swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent},
2828
tcp, yamux, Multiaddr, PeerId, Transport,
2929
};
3030
use std::time::Duration;
@@ -50,10 +50,10 @@ async fn main() {
5050
MyBehaviour {
5151
rendezvous: rendezvous::client::Behaviour::new(key_pair.clone()),
5252
ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))),
53-
keep_alive: keep_alive::Behaviour,
5453
},
5554
PeerId::from(key_pair.public()),
5655
)
56+
.idle_connection_timeout(Duration::from_secs(5))
5757
.build();
5858

5959
swarm.dial(rendezvous_point_address.clone()).unwrap();
@@ -127,5 +127,4 @@ async fn main() {
127127
struct MyBehaviour {
128128
rendezvous: rendezvous::client::Behaviour,
129129
ping: ping::Behaviour,
130-
keep_alive: keep_alive::Behaviour,
131130
}

examples/rendezvous/src/bin/rzv-identify.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use futures::StreamExt;
2222
use libp2p::{
2323
core::transport::upgrade::Version,
2424
identify, identity, noise, ping, rendezvous,
25-
swarm::{keep_alive, NetworkBehaviour, SwarmBuilder, SwarmEvent},
25+
swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent},
2626
tcp, yamux, Multiaddr, PeerId, Transport,
2727
};
2828
use std::time::Duration;
@@ -50,10 +50,10 @@ async fn main() {
5050
)),
5151
rendezvous: rendezvous::client::Behaviour::new(key_pair.clone()),
5252
ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))),
53-
keep_alive: keep_alive::Behaviour,
5453
},
5554
PeerId::from(key_pair.public()),
5655
)
56+
.idle_connection_timeout(Duration::from_secs(5))
5757
.build();
5858

5959
let _ = swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse().unwrap());
@@ -133,5 +133,4 @@ struct MyBehaviour {
133133
identify: identify::Behaviour,
134134
rendezvous: rendezvous::client::Behaviour,
135135
ping: ping::Behaviour,
136-
keep_alive: keep_alive::Behaviour,
137136
}

examples/rendezvous/src/bin/rzv-register.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use futures::StreamExt;
2222
use libp2p::{
2323
core::transport::upgrade::Version,
2424
identity, noise, ping, rendezvous,
25-
swarm::{keep_alive, NetworkBehaviour, SwarmBuilder, SwarmEvent},
25+
swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent},
2626
tcp, yamux, Multiaddr, PeerId, Transport,
2727
};
2828
use std::time::Duration;
@@ -46,10 +46,10 @@ async fn main() {
4646
MyBehaviour {
4747
rendezvous: rendezvous::client::Behaviour::new(key_pair.clone()),
4848
ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))),
49-
keep_alive: keep_alive::Behaviour,
5049
},
5150
PeerId::from(key_pair.public()),
5251
)
52+
.idle_connection_timeout(Duration::from_secs(5))
5353
.build();
5454

5555
// In production the external address should be the publicly facing IP address of the rendezvous point.
@@ -130,5 +130,4 @@ async fn main() {
130130
struct MyBehaviour {
131131
rendezvous: rendezvous::client::Behaviour,
132132
ping: ping::Behaviour,
133-
keep_alive: keep_alive::Behaviour,
134133
}

examples/rendezvous/src/main.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use futures::StreamExt;
2424
use libp2p::{
2525
core::transport::upgrade::Version,
2626
identify, identity, noise, ping, rendezvous,
27-
swarm::{keep_alive, NetworkBehaviour, SwarmBuilder, SwarmEvent},
27+
swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent},
2828
tcp, yamux, PeerId, Transport,
2929
};
3030
use std::time::Duration;
@@ -48,10 +48,10 @@ async fn main() {
4848
)),
4949
rendezvous: rendezvous::server::Behaviour::new(rendezvous::server::Config::default()),
5050
ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))),
51-
keep_alive: keep_alive::Behaviour,
5251
},
5352
PeerId::from(key_pair.public()),
5453
)
54+
.idle_connection_timeout(Duration::from_secs(5))
5555
.build();
5656

5757
let _ = swarm.listen_on("/ip4/0.0.0.0/tcp/62649".parse().unwrap());
@@ -97,5 +97,4 @@ struct MyBehaviour {
9797
identify: identify::Behaviour,
9898
rendezvous: rendezvous::server::Behaviour,
9999
ping: ping::Behaviour,
100-
keep_alive: keep_alive::Behaviour,
101100
}

interop-tests/src/lib.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use std::time::Duration;
33

44
use anyhow::{bail, Context, Result};
55
use futures::{FutureExt, StreamExt};
6-
use libp2p::swarm::{keep_alive, NetworkBehaviour, SwarmEvent};
7-
use libp2p::{identify, identity, ping, Multiaddr, PeerId};
6+
use libp2p::swarm::SwarmEvent;
7+
use libp2p::{identify, identity, ping, swarm::NetworkBehaviour, Multiaddr, PeerId};
88
#[cfg(target_arch = "wasm32")]
99
use wasm_bindgen::prelude::*;
1010

@@ -33,8 +33,7 @@ pub async fn run_test(
3333
let mut swarm = swarm_builder(
3434
boxed_transport,
3535
Behaviour {
36-
ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))),
37-
keep_alive: keep_alive::Behaviour,
36+
ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(10))),
3837
// Need to include identify until https://github.com/status-im/nim-libp2p/issues/924 is resolved.
3938
identify: identify::Behaviour::new(identify::Config::new(
4039
"/interop-tests".to_owned(),
@@ -43,6 +42,7 @@ pub async fn run_test(
4342
},
4443
local_peer_id,
4544
)
45+
.idle_connection_timeout(Duration::from_secs(5))
4646
.build();
4747

4848
log::info!("Running ping test: {}", swarm.local_peer_id());
@@ -242,7 +242,6 @@ impl FromStr for SecProtocol {
242242
#[derive(NetworkBehaviour)]
243243
struct Behaviour {
244244
ping: ping::Behaviour,
245-
keep_alive: keep_alive::Behaviour,
246245
identify: identify::Behaviour,
247246
}
248247

0 commit comments

Comments
 (0)