Skip to content

Commit

Permalink
feat(swarm): set default for idle-connection-timeout to 10s (#4967)
Browse files Browse the repository at this point in the history
## Description

With the move to a global idle-connection-timeout, connections are being
closed much more aggressively. This causes problems in situations where,
e.g. an application wants to use a connection shortly after an event has
been emitted from the `Swarm`. With a default of 0 seconds, such a
connection is instantly considered idle and therefore closed, despite
the application wanting to use it again just moments later. Whilst it is
possible to structure application code to mitigate this, it is
unnecessarily complicated.

Additionally, connections being closed instantly if not in use is a
foot-gun for newcomers to the library.

From a technical point-of-view, instantly closing idle connections is
nice. In reality, it is an impractical default. Hence, we change this
default to 10s.

10 seconds is considered to be an acceptable default as it strikes a
balance between allowing some pause between network activity, yet frees
up resources that are (supposedly) no longer needed.

Resolves: #4912.
  • Loading branch information
thomaseizinger authored Dec 13, 2024
1 parent be28c96 commit f4edafb
Show file tree
Hide file tree
Showing 26 changed files with 34 additions and 79 deletions.
1 change: 0 additions & 1 deletion examples/autonat/src/bin/autonat_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
yamux::Config::default,
)?
.with_behaviour(|key| Behaviour::new(key.public()))?
.with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(60)))
.build();

swarm.listen_on(
Expand Down
3 changes: 1 addition & 2 deletions examples/autonat/src/bin/autonat_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#![doc = include_str!("../../README.md")]

use std::{error::Error, net::Ipv4Addr, time::Duration};
use std::{error::Error, net::Ipv4Addr};

use clap::Parser;
use futures::StreamExt;
Expand Down Expand Up @@ -56,7 +56,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
yamux::Config::default,
)?
.with_behaviour(|key| Behaviour::new(key.public()))?
.with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(60)))
.build();

swarm.listen_on(
Expand Down
10 changes: 1 addition & 9 deletions examples/browser-webrtc/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#![allow(non_upper_case_globals)]

use std::{
net::{Ipv4Addr, SocketAddr},
time::Duration,
};
use std::net::{Ipv4Addr, SocketAddr};

use anyhow::Result;
use axum::{
Expand Down Expand Up @@ -41,11 +38,6 @@ async fn main() -> anyhow::Result<()> {
.map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn))))
})?
.with_behaviour(|_| ping::Behaviour::default())?
.with_swarm_config(|cfg| {
cfg.with_idle_connection_timeout(
Duration::from_secs(u64::MAX), // Allows us to observe the pings.
)
})
.build();

let address_webrtc = Multiaddr::from(Ipv4Addr::UNSPECIFIED)
Expand Down
1 change: 0 additions & 1 deletion examples/chat/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
mdns::tokio::Behaviour::new(mdns::Config::default(), key.public().to_peer_id())?;
Ok(MyBehaviour { gossipsub, mdns })
})?
.with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(60)))
.build();

// Create a Gossipsub topic
Expand Down
3 changes: 1 addition & 2 deletions examples/dcutr/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#![doc = include_str!("../README.md")]

use std::{error::Error, str::FromStr, time::Duration};
use std::{error::Error, str::FromStr};

use clap::Parser;
use futures::{executor::block_on, future::FutureExt, stream::StreamExt};
Expand Down Expand Up @@ -105,7 +105,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
)),
dcutr: dcutr::Behaviour::new(keypair.public().to_peer_id()),
})?
.with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(60)))
.build();

swarm
Expand Down
3 changes: 1 addition & 2 deletions examples/distributed-key-value-store/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#![doc = include_str!("../README.md")]

use std::{error::Error, time::Duration};
use std::error::Error;

use futures::stream::StreamExt;
use libp2p::{
Expand Down Expand Up @@ -68,7 +68,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
)?,
})
})?
.with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(60)))
.build();

swarm.behaviour_mut().kademlia.set_mode(Some(Mode::Server));
Expand Down
3 changes: 1 addition & 2 deletions examples/identify/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#![doc = include_str!("../README.md")]

use std::{error::Error, time::Duration};
use std::error::Error;

use futures::StreamExt;
use libp2p::{core::multiaddr::Multiaddr, identify, noise, swarm::SwarmEvent, tcp, yamux};
Expand All @@ -45,7 +45,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
key.public(),
))
})?
.with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(60)))
.build();

// Tell the swarm to listen on all interfaces and a random, OS-assigned
Expand Down
1 change: 0 additions & 1 deletion examples/ipfs-kad/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ async fn main() -> Result<()> {
let store = kad::store::MemoryStore::new(key.public().to_peer_id());
kad::Behaviour::with_config(key.public().to_peer_id(), store, cfg)
})?
.with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5)))
.build();

// Add the bootnodes to the local routing table. `libp2p-dns` built
Expand Down
3 changes: 1 addition & 2 deletions examples/ipfs-private/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#![doc = include_str!("../README.md")]

use std::{env, error::Error, fs, path::Path, str::FromStr, time::Duration};
use std::{env, error::Error, fs, path::Path, str::FromStr};

use either::Either;
use futures::prelude::*;
Expand Down Expand Up @@ -152,7 +152,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
ping: ping::Behaviour::new(ping::Config::new()),
})
})?
.with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(60)))
.build();

println!("Subscribing to {gossipsub_topic:?}");
Expand Down
3 changes: 1 addition & 2 deletions examples/metrics/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#![doc = include_str!("../README.md")]

use std::{error::Error, time::Duration};
use std::error::Error;

use futures::StreamExt;
use libp2p::{
Expand Down Expand Up @@ -54,7 +54,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
)?
.with_bandwidth_metrics(&mut metric_registry)
.with_behaviour(|key| Behaviour::new(key.public()))?
.with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(u64::MAX)))
.build();

swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;
Expand Down
1 change: 0 additions & 1 deletion examples/rendezvous/src/bin/rzv-discover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
rendezvous: rendezvous::client::Behaviour::new(key.clone()),
ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))),
})?
.with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(5)))
.build();

swarm.dial(rendezvous_point_address.clone()).unwrap();
Expand Down
1 change: 0 additions & 1 deletion examples/rendezvous/src/bin/rzv-identify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ async fn main() {
ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))),
})
.unwrap()
.with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(5)))
.build();

let _ = swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse().unwrap());
Expand Down
1 change: 0 additions & 1 deletion examples/rendezvous/src/bin/rzv-register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ async fn main() {
ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))),
})
.unwrap()
.with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(5)))
.build();

// In production the external address should be the publicly facing IP address of the rendezvous
Expand Down
1 change: 0 additions & 1 deletion examples/rendezvous/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
rendezvous: rendezvous::server::Behaviour::new(rendezvous::server::Config::default()),
ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))),
})?
.with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(5)))
.build();

let _ = swarm.listen_on("/ip4/0.0.0.0/tcp/62649".parse().unwrap());
Expand Down
10 changes: 0 additions & 10 deletions interop-tests/src/arch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ pub(crate) mod native {
.with_tokio()
.with_quic()
.with_behaviour(behaviour_constructor)?
.with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5)))
.build(),
format!("/ip4/{ip}/udp/0/quic-v1"),
),
Expand All @@ -62,7 +61,6 @@ pub(crate) mod native {
mplex::MplexConfig::default,
)?
.with_behaviour(behaviour_constructor)?
.with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5)))
.build(),
format!("/ip4/{ip}/tcp/0"),
),
Expand All @@ -75,7 +73,6 @@ pub(crate) mod native {
yamux::Config::default,
)?
.with_behaviour(behaviour_constructor)?
.with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5)))
.build(),
format!("/ip4/{ip}/tcp/0"),
),
Expand All @@ -88,7 +85,6 @@ pub(crate) mod native {
mplex::MplexConfig::default,
)?
.with_behaviour(behaviour_constructor)?
.with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5)))
.build(),
format!("/ip4/{ip}/tcp/0"),
),
Expand All @@ -101,7 +97,6 @@ pub(crate) mod native {
yamux::Config::default,
)?
.with_behaviour(behaviour_constructor)?
.with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5)))
.build(),
format!("/ip4/{ip}/tcp/0"),
),
Expand All @@ -111,7 +106,6 @@ pub(crate) mod native {
.with_websocket(tls::Config::new, mplex::MplexConfig::default)
.await?
.with_behaviour(behaviour_constructor)?
.with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5)))
.build(),
format!("/ip4/{ip}/tcp/0/ws"),
),
Expand All @@ -121,7 +115,6 @@ pub(crate) mod native {
.with_websocket(tls::Config::new, yamux::Config::default)
.await?
.with_behaviour(behaviour_constructor)?
.with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5)))
.build(),
format!("/ip4/{ip}/tcp/0/ws"),
),
Expand All @@ -131,7 +124,6 @@ pub(crate) mod native {
.with_websocket(noise::Config::new, mplex::MplexConfig::default)
.await?
.with_behaviour(behaviour_constructor)?
.with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5)))
.build(),
format!("/ip4/{ip}/tcp/0/ws"),
),
Expand All @@ -141,7 +133,6 @@ pub(crate) mod native {
.with_websocket(noise::Config::new, yamux::Config::default)
.await?
.with_behaviour(behaviour_constructor)?
.with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5)))
.build(),
format!("/ip4/{ip}/tcp/0/ws"),
),
Expand All @@ -155,7 +146,6 @@ pub(crate) mod native {
))
})?
.with_behaviour(behaviour_constructor)?
.with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5)))
.build(),
format!("/ip4/{ip}/udp/0/webrtc-direct"),
),
Expand Down
2 changes: 2 additions & 0 deletions libp2p/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

- Deprecate `void` crate.
See [PR 5676](https://github.com/libp2p/rust-libp2p/pull/5676).
- Update default for idle-connection-timeout to 10s.
See [PR 4967](https://github.com/libp2p/rust-libp2p/pull/4967).

- Expose swarm builder phase errors.
See [PR 5726](https://github.com/libp2p/rust-libp2p/pull/5726).
Expand Down
1 change: 0 additions & 1 deletion libp2p/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ clap = { version = "4.1.6", features = ["derive"] }
tokio = { workspace = true, features = [ "io-util", "io-std", "macros", "rt", "rt-multi-thread"] }

libp2p-mplex = { workspace = true }
libp2p-noise = { workspace = true }
libp2p-tcp = { workspace = true, features = ["tokio"] }
tracing-subscriber = { workspace = true, features = ["env-filter"] }

Expand Down
9 changes: 0 additions & 9 deletions libp2p/src/tutorials/ping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,6 @@
//! yamux::Config::default,
//! )?
//! .with_behaviour(|_| ping::Behaviour::default())?
//! .with_swarm_config(|cfg| {
//! cfg.with_idle_connection_timeout(Duration::from_secs(u64::MAX))
//! })
//! .build();
//!
//! Ok(())
Expand Down Expand Up @@ -287,9 +284,6 @@
//! yamux::Config::default,
//! )?
//! .with_behaviour(|_| ping::Behaviour::default())?
//! .with_swarm_config(|cfg| {
//! cfg.with_idle_connection_timeout(Duration::from_secs(u64::MAX))
//! })
//! .build();
//!
//! // Tell the swarm to listen on all interfaces and a random, OS-assigned
Expand Down Expand Up @@ -335,9 +329,6 @@
//! yamux::Config::default,
//! )?
//! .with_behaviour(|_| ping::Behaviour::default())?
//! .with_swarm_config(|cfg| {
//! cfg.with_idle_connection_timeout(Duration::from_secs(u64::MAX))
//! })
//! .build();
//!
//! // Tell the swarm to listen on all interfaces and a random, OS-assigned
Expand Down
3 changes: 1 addition & 2 deletions protocols/kad/src/behaviour/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ fn build_node_with_config(cfg: Config) -> (Multiaddr, TestSwarm) {
transport,
behaviour,
local_id,
swarm::Config::with_async_std_executor()
.with_idle_connection_timeout(Duration::from_secs(5)),
swarm::Config::with_async_std_executor(),
);

let address: Multiaddr = Protocol::Memory(random::<u64>()).into();
Expand Down
5 changes: 1 addition & 4 deletions protocols/relay/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,10 +416,7 @@ fn reuse_connection() {
.with(Protocol::P2p(relay_peer_id))
.with(Protocol::P2pCircuit);

// To reuse the connection, we need to ensure it is not shut down due to being idle.
let mut client = build_client_with_config(
Config::with_async_std_executor().with_idle_connection_timeout(Duration::from_secs(1)),
);
let mut client = build_client();
let client_peer_id = *client.local_peer_id();

client.dial(relay_addr).unwrap();
Expand Down
2 changes: 2 additions & 0 deletions swarm-test/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

- Add `tokio` runtime support and make `tokio` and `async-std` runtimes optional behind features.
See [PR 5551].
- Update default for idle-connection-timeout to 10s on `SwarmExt::new_ephemeral` methods.
See [PR 4967](https://github.com/libp2p/rust-libp2p/pull/4967).

[PR 5551]: https://github.com/libp2p/rust-libp2p/pull/5551

Expand Down
15 changes: 2 additions & 13 deletions swarm-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,13 +246,7 @@ where
transport,
behaviour_fn(identity),
peer_id,
libp2p_swarm::Config::with_async_std_executor()
// Some tests need
// connections to be kept
// alive beyond what the
// individual behaviour
// configures.,
.with_idle_connection_timeout(Duration::from_secs(5)),
libp2p_swarm::Config::with_async_std_executor(),
)
}

Expand All @@ -279,12 +273,7 @@ where
transport,
behaviour_fn(identity),
peer_id,
libp2p_swarm::Config::with_tokio_executor()
.with_idle_connection_timeout(Duration::from_secs(5)), /* Some tests need
* connections to be kept
* alive beyond what the
* individual behaviour
* configures., */
libp2p_swarm::Config::with_tokio_executor(),
)
}

Expand Down
5 changes: 4 additions & 1 deletion swarm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@

- Deprecate `void` crate.
See [PR 5676](https://github.com/libp2p/rust-libp2p/pull/5676).

- Fix `cargo clippy` warnings in `rustc 1.84.0-beta.1`.
See [PR 5700](https://github.com/libp2p/rust-libp2p/pull/5700).

- Update default for idle-connection-timeout to 10s.
See [PR 4967](https://github.com/libp2p/rust-libp2p/pull/4967).

## 0.45.1

- Update `libp2p-swarm-derive` to version `0.35.0`, see [PR 5545]
Expand Down
2 changes: 1 addition & 1 deletion swarm/src/connection/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -989,7 +989,7 @@ impl PoolConfig {
task_command_buffer_size: 32,
per_connection_event_buffer_size: 7,
dial_concurrency_factor: NonZeroU8::new(8).expect("8 > 0"),
idle_connection_timeout: Duration::ZERO,
idle_connection_timeout: Duration::from_secs(10),
substream_upgrade_protocol_override: None,
max_negotiating_inbound_streams: 128,
}
Expand Down
Loading

0 comments on commit f4edafb

Please sign in to comment.