Skip to content

Commit 972927d

Browse files
pefontanapefontana
andauthored
feat: Add Downloader::with_pool_options() constructor (#213)
Adds a `Downloader::with_pool_options()` constructor that allows configuring the internal `ConnectionPool` options. Currently `Downloader::new()` hardcodes `Default::default()` for pool options, which means the `idle_timeout` is always 5 seconds. The `ConnectionPool` and `Options` types are already public, but there's no way to pass them through to the `Downloader`. We're from the [Psyche/Nousnet](https://github.com/PsycheFoundation/nousnet) team In our use case, peers exchange gradient via iroh-blobs. With the 5s idle timeout, every connection gets dropped between transfers and a new one is created for the next round. On a devnet run with 6 peers, over 8 hours we see: ``` MaxPathIdReached warnings: 3,098 NAT traversal warnings: 3,344 Connection open/close cycles per hour: ~1,300 Handshake aborts: 31 ``` ``` 2025-03-09T10:15:02 WARN iroh: MaxPathIdReached for connection ... 2025-03-09T10:15:02 WARN iroh: NAT traversal to ... via ... failed 2025-03-09T10:15:03 new connection to peer ... 2025-03-09T10:15:25 connection closed (idle timeout) 2025-03-09T10:15:25 new connection to peer ... <- same peer, 22s later ``` The `MaxPathIdReached` happens because QUIC path IDs are monotonically increasing and never reused, constant connection churn burns through them. Being able to set a longer idle timeout (e.g. 60s) would let the pool reuse connections across transfers, eliminating the churn entirely. Here is how we plan to use it on NousNet https://github.com/PsycheFoundation/nousnet/pull/600/changes Feedback is really appreciated --------- Signed-off-by: pefontana <fontana.pedro93@gmail.com> Co-authored-by: pefontana <pedro@nous.com>
1 parent 2088701 commit 972927d

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

src/api/downloader.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,14 @@ pub enum DownloadProgressItem {
6464
}
6565

6666
impl DownloaderActor {
67-
fn new(store: Store, endpoint: Endpoint) -> Self {
67+
fn new_with_opts(
68+
store: Store,
69+
endpoint: Endpoint,
70+
pool_options: crate::util::connection_pool::Options,
71+
) -> Self {
6872
Self {
6973
store,
70-
pool: ConnectionPool::new(endpoint, crate::ALPN, Default::default()),
74+
pool: ConnectionPool::new(endpoint, crate::ALPN, pool_options),
7175
tasks: JoinSet::new(),
7276
running: HashSet::new(),
7377
}
@@ -341,8 +345,16 @@ impl IntoFuture for DownloadProgress {
341345

342346
impl Downloader {
343347
pub fn new(store: &Store, endpoint: &Endpoint) -> Self {
348+
Self::new_with_opts(store, endpoint, Default::default())
349+
}
350+
351+
pub fn new_with_opts(
352+
store: &Store,
353+
endpoint: &Endpoint,
354+
pool_options: crate::util::connection_pool::Options,
355+
) -> Self {
344356
let (tx, rx) = tokio::sync::mpsc::channel::<SwarmMsg>(32);
345-
let actor = DownloaderActor::new(store.clone(), endpoint.clone());
357+
let actor = DownloaderActor::new_with_opts(store.clone(), endpoint.clone(), pool_options);
346358
n0_future::task::spawn(actor.run(rx));
347359
Self { client: tx.into() }
348360
}

0 commit comments

Comments
 (0)