From fcc6964692e9e50537d6d25d9427cde1d9acefce Mon Sep 17 00:00:00 2001 From: lunar-mining Date: Sat, 25 Jun 2022 12:55:00 +0200 Subject: [PATCH] net/ seed_session: fix bug which caused seed to drop previously we were looping through all start_seed tasks linearily and applying a global timer for all tasks. if any tasks exceeded the timer, all tasks after the timeout were dropped. here we implement a unique timer for every unique task. if the task exceeds a timer, that task is dropped, with no impact on any future tasks. --- src/net/session/seed_session.rs | 44 +++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/net/session/seed_session.rs b/src/net/session/seed_session.rs index 7d6f939c4..b457a937e 100644 --- a/src/net/session/seed_session.rs +++ b/src/net/session/seed_session.rs @@ -2,6 +2,7 @@ use async_std::{ future::timeout, sync::{Arc, Weak}, }; +use futures::future; use std::time::Duration; use async_executor::Executor; @@ -49,29 +50,34 @@ impl SeedSession { let mut tasks = Vec::new(); + // This loops through all the seeds and tries to start them. + // If the seed_query_timeout_seconds times out before they are finished, + // it will return an error. for (i, seed) in settings.seeds.iter().enumerate() { - tasks.push(executor.spawn(self.clone().start_seed(i, seed.clone(), executor.clone()))); - } + let ex2 = executor.clone(); + let self2 = self.clone(); + let sett2 = settings.clone(); + tasks.push(async move { + let task = self2.clone().start_seed(i, seed.clone(), ex2.clone()); - // This line loops through all the tasks and waits for them to finish. - // But if the seed_query_timeout_seconds times out before they are finished, - // then it will simply quit and the tasks will get dropped. - let result = - timeout(Duration::from_secs(settings.seed_query_timeout_seconds.into()), async move { - for (i, task) in tasks.into_iter().enumerate() { - // Ignore errors - match task.await { - Ok(()) => info!("Successfully queried seed #{}", i), - Err(err) => warn!("Seed query #{} failed for reason: {}", i, err), - } + let result = + timeout(Duration::from_secs(sett2.seed_query_timeout_seconds.into()), task) + .await; + + match result { + Ok(t) => match t { + Ok(()) => { + info!("Seed #{} connected successfully", i) + } + Err(err) => { + warn!("Seed #{} failed for reason {}", i, err) + } + }, + Err(_err) => error!("Seed #{} timed out", i), } - }) - .await; - - if result.is_err() { - error!("Querying seeds timed out"); - return Err(Error::NetworkOperationFailed) + }); } + future::join_all(tasks).await; // Seed process complete if self.p2p().hosts().is_empty().await {