Skip to content

Commit a367e1b

Browse files
authored
feat(kad): configurable outbound_substreams timeout
Then testing `put_record_to` with poor connectioin but large packet size (around 4MB), the `put_record_to` frequently got failed and the PutRecordToError::stats showing always failed at 10s. ``` "kad_event::PutRecordError::QuorumFailed", required quorum 2, stored on [], QueryStats { requests: 5, success: 0, failure: 5, start: Some(Instant { tv_sec: 121323, tv_nsec: 961187829 }), end: Some(Instant { tv_sec: 121334, tv_nsec: 188694869 }) } - ProgressStep { count: 1, last: true } ``` However, this timeout is not defined by request/response protocol timeout (which in our case increased to 30s already). Further digging through the libp2p code, it turned out this timeout is actually affected by outbound_substreams timeout. We tested with increase to 30s, do see much less put_record_to failure and QueryStats showing extended completion duration (larger than 10s, and in case of failed, to be 30s). Hence raised this PR to provide a configurable approach of the timeout. Pull-Request: libp2p#6015.
1 parent 9bec5e6 commit a367e1b

File tree

7 files changed

+37
-6
lines changed

7 files changed

+37
-6
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ libp2p-floodsub = { version = "0.46.1", path = "protocols/floodsub" }
8585
libp2p-gossipsub = { version = "0.49.0", path = "protocols/gossipsub" }
8686
libp2p-identify = { version = "0.47.0", path = "protocols/identify" }
8787
libp2p-identity = { version = "0.2.11" }
88-
libp2p-kad = { version = "0.47.0", path = "protocols/kad" }
88+
libp2p-kad = { version = "0.47.1", path = "protocols/kad" }
8989
libp2p-mdns = { version = "0.47.0", path = "protocols/mdns" }
9090
libp2p-memory-connection-limits = { version = "0.4.0", path = "misc/memory-connection-limits" }
9191
libp2p-metrics = { version = "0.17.0", path = "misc/metrics" }

protocols/kad/CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 0.47.1
2+
3+
- Configurable outbound_substreams_timeout.
4+
See [PR 6015](https://github.com/libp2p/rust-libp2p/pull/6015).
5+
16
## 0.47.0
27

38
- Expose a kad query facility allowing specify num_results dynamically.
@@ -15,7 +20,7 @@
1520
- Remove deprecated default constructor for `ProtocolConfig`.
1621
See [PR 5774](https://github.com/libp2p/rust-libp2p/pull/5774).
1722
- Add lazy cleanup for expired provider records in `Behavior::get_providers` and `Behavior::provider_peers`.
18-
See [PR 5980](https://github.com/libp2p/rust-libp2p/pull/5980)
23+
See [PR 5980](https://github.com/libp2p/rust-libp2p/pull/5980).
1924

2025
<!-- Update to libp2p-core v0.43.0 -->
2126

protocols/kad/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "libp2p-kad"
33
edition.workspace = true
44
rust-version = { workspace = true }
55
description = "Kademlia protocol for libp2p"
6-
version = "0.47.0"
6+
version = "0.47.1"
77
authors = ["Parity Technologies <[email protected]>"]
88
license = "MIT"
99
repository = "https://github.com/libp2p/rust-libp2p"

protocols/kad/src/behaviour.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,16 @@ impl Config {
382382
self
383383
}
384384

385+
/// Modifies the timeout duration of outbount_substreams.
386+
///
387+
/// * Default to `10` seconds.
388+
/// * May need to increase this value when sending large records with poor connection.
389+
pub fn set_outbound_substreams_timeout(&mut self, timeout: Duration) -> &mut Self {
390+
self.protocol_config
391+
.set_outbound_substreams_timeout(timeout);
392+
self
393+
}
394+
385395
/// Sets the k-bucket insertion strategy for the Kademlia routing table.
386396
pub fn set_kbucket_inserts(&mut self, inserts: BucketInserts) -> &mut Self {
387397
self.kbucket_inserts = inserts;

protocols/kad/src/handler.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use std::{
2424
marker::PhantomData,
2525
pin::Pin,
2626
task::{Context, Poll, Waker},
27-
time::Duration,
2827
};
2928

3029
use either::Either;
@@ -454,6 +453,8 @@ impl Handler {
454453
}
455454
}
456455

456+
let outbound_substreams_timeout = protocol_config.outbound_substreams_timeout_s();
457+
457458
Handler {
458459
protocol_config,
459460
mode,
@@ -462,7 +463,7 @@ impl Handler {
462463
next_connec_unique_id: UniqueConnecId(0),
463464
inbound_substreams: Default::default(),
464465
outbound_substreams: futures_bounded::FuturesTupleSet::new(
465-
Duration::from_secs(10),
466+
outbound_substreams_timeout,
466467
MAX_NUM_STREAMS,
467468
),
468469
pending_streams: Default::default(),

protocols/kad/src/protocol.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ use crate::{
4949
pub(crate) const DEFAULT_PROTO_NAME: StreamProtocol = StreamProtocol::new("/ipfs/kad/1.0.0");
5050
/// The default maximum size for a varint length-delimited packet.
5151
pub(crate) const DEFAULT_MAX_PACKET_SIZE: usize = 16 * 1024;
52+
/// The default timeout of outbound_substreams to be 10 (seconds).
53+
const DEFAULT_OUTBOUND_SUBSTREAMS_TIMEOUT_S: Duration = Duration::from_secs(10);
5254
/// Status of our connection to a node reported by the Kademlia protocol.
5355
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
5456
pub enum ConnectionType {
@@ -145,6 +147,8 @@ pub struct ProtocolConfig {
145147
protocol_names: Vec<StreamProtocol>,
146148
/// Maximum allowed size of a packet.
147149
max_packet_size: usize,
150+
/// Specifies the outbound_substreams timeout in seconds
151+
outbound_substreams_timeout_s: Duration,
148152
}
149153

150154
impl ProtocolConfig {
@@ -153,6 +157,7 @@ impl ProtocolConfig {
153157
ProtocolConfig {
154158
protocol_names: vec![protocol_name],
155159
max_packet_size: DEFAULT_MAX_PACKET_SIZE,
160+
outbound_substreams_timeout_s: DEFAULT_OUTBOUND_SUBSTREAMS_TIMEOUT_S,
156161
}
157162
}
158163

@@ -165,6 +170,16 @@ impl ProtocolConfig {
165170
pub fn set_max_packet_size(&mut self, size: usize) {
166171
self.max_packet_size = size;
167172
}
173+
174+
/// Modifies outbount_substreams timeout.
175+
pub fn set_outbound_substreams_timeout(&mut self, timeout: Duration) {
176+
self.outbound_substreams_timeout_s = timeout;
177+
}
178+
179+
/// Getter of outbount_substreams_timeout_s.
180+
pub fn outbound_substreams_timeout_s(&self) -> Duration {
181+
self.outbound_substreams_timeout_s
182+
}
168183
}
169184

170185
impl UpgradeInfo for ProtocolConfig {

0 commit comments

Comments
 (0)