From 2192f70b8d04203b11289838505bdebdd9b1d29a Mon Sep 17 00:00:00 2001 From: ghassmo Date: Tue, 12 Apr 2022 09:16:47 +0400 Subject: [PATCH] src/net: fix a bug causing intensive CPU usage --- src/net/hosts.rs | 6 ------ src/net/session/outbound_session.rs | 30 +++++++++++++++-------------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/net/hosts.rs b/src/net/hosts.rs index 6e34cf0e3..35412f5f7 100644 --- a/src/net/hosts.rs +++ b/src/net/hosts.rs @@ -2,7 +2,6 @@ use async_std::sync::Mutex; use std::{net::SocketAddr, sync::Arc}; use fxhash::FxHashSet; -use rand::seq::SliceRandom; /// Pointer to hosts class. pub type HostsPtr = Arc; @@ -31,11 +30,6 @@ impl Hosts { } } - /// Return a single host address. - pub async fn load_single(&self) -> Option { - self.addrs.lock().await.choose(&mut rand::thread_rng()).cloned() - } - /// Return the list of hosts. pub async fn load_all(&self) -> Vec { self.addrs.lock().await.clone() diff --git a/src/net/session/outbound_session.rs b/src/net/session/outbound_session.rs index bd8c3751c..bcf14f1d8 100644 --- a/src/net/session/outbound_session.rs +++ b/src/net/session/outbound_session.rs @@ -1,4 +1,4 @@ -use async_std::{sync::Mutex, task::yield_now}; +use async_std::sync::Mutex; use std::{ fmt, net::SocketAddr, @@ -8,6 +8,7 @@ use std::{ use async_executor::Executor; use async_trait::async_trait; use log::{error, info}; +use rand::seq::SliceRandom; use serde_json::json; use crate::{ @@ -189,24 +190,18 @@ impl OutboundSession { /// found that passes all checks. async fn load_address(&self, slot_number: u32) -> Result { let p2p = self.p2p(); - let hosts = p2p.hosts(); let self_inbound_addr = p2p.settings().external_addr; - loop { - yield_now().await; + let mut addrs; - let addr = hosts.load_single().await; + { + let hosts = p2p.hosts().load_all().await; + addrs = hosts.clone(); + } - if addr.is_none() { - error!(target: "net", "Hosts address pool is empty. Closing connect slot #{}", slot_number); - return Err(Error::ServiceStopped) - } - let addr = addr.unwrap(); - - if Self::is_self_inbound(&addr, &self_inbound_addr) { - continue - } + addrs.shuffle(&mut rand::thread_rng()); + for addr in addrs { if p2p.exists(&addr).await { continue } @@ -216,8 +211,15 @@ impl OutboundSession { continue } + if Self::is_self_inbound(&addr, &self_inbound_addr) { + continue + } + return Ok(addr) } + + error!(target: "net", "Hosts address pool is empty. Closing connect slot #{}", slot_number); + Err(Error::ServiceStopped) } /// Checks whether an address is our own inbound address to avoid connecting