Răsfoiți Sursa

src/net: fix a bug causing intensive CPU usage

ghassmo 4 ani în urmă
părinte
comite
2192f70b8d
2 a modificat fișierele cu 16 adăugiri și 20 ștergeri
  1. 0 6
      src/net/hosts.rs
  2. 16 14
      src/net/session/outbound_session.rs

+ 0 - 6
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<Hosts>;
@@ -31,11 +30,6 @@ impl Hosts {
         }
     }
 
-    /// Return a single host address.
-    pub async fn load_single(&self) -> Option<SocketAddr> {
-        self.addrs.lock().await.choose(&mut rand::thread_rng()).cloned()
-    }
-
     /// Return the list of hosts.
     pub async fn load_all(&self) -> Vec<SocketAddr> {
         self.addrs.lock().await.clone()

+ 16 - 14
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<SocketAddr> {
         let p2p = self.p2p();
-        let hosts = p2p.hosts();
         let self_inbound_addr = p2p.settings().external_addr;
 
-        loop {
-            yield_now().await;
-
-            let addr = hosts.load_single().await;
+        let mut addrs;
 
-            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();
+        {
+            let hosts = p2p.hosts().load_all().await;
+            addrs = hosts.clone();
+        }
 
-            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