mirror of
https://github.com/threefoldtech/mycelium.git
synced 2026-10-23 22:12:20 +00:00
Close #616: Keep track of peer connection times
Signed-off-by: Lee Smet <lee.smet@hotmail.com>
This commit is contained in:
3 files changed
+54
-2
No files matched your search
@@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- When a route is used which is about to expire, we now send a route request to
|
||||
try and refresh its duration before it expires.
|
||||
- We now track when a peer was fist discovered and when we last connected to it.
|
||||
This info is displayed in the CLI when listing peers.
|
||||
|
||||
### Fixed
|
||||
|
||||
|
||||
@@ -37,7 +37,9 @@ pub async fn list_peers(
|
||||
"Type",
|
||||
"Connection",
|
||||
"Rx total",
|
||||
"Tx total"
|
||||
"Tx total",
|
||||
"Discovered",
|
||||
"Last connection"
|
||||
]);
|
||||
for peer in peers.iter() {
|
||||
table.add_row(row![
|
||||
@@ -47,6 +49,10 @@ pub async fn list_peers(
|
||||
peer.connection_state,
|
||||
format_bytes(peer.rx_bytes),
|
||||
format_bytes(peer.tx_bytes),
|
||||
format_seconds(peer.discovered),
|
||||
peer.last_connected
|
||||
.map(format_seconds)
|
||||
.unwrap_or("Never connected".to_string()),
|
||||
]);
|
||||
}
|
||||
table.printstd();
|
||||
@@ -69,6 +75,24 @@ fn format_bytes(bytes: u64) -> String {
|
||||
)
|
||||
}
|
||||
|
||||
/// Convert an amount of seconds into a human readable string.
|
||||
fn format_seconds(total_seconds: u64) -> String {
|
||||
let seconds = total_seconds % 60;
|
||||
let minutes = (total_seconds / 60) % 60;
|
||||
let hours = (total_seconds / 3600) % 60;
|
||||
let days = (total_seconds / 86400) % 60;
|
||||
|
||||
if days > 0 {
|
||||
format!("{days}d {hours}h {minutes}m {seconds}s")
|
||||
} else if hours > 0 {
|
||||
format!("{hours}h {minutes}m {seconds}s")
|
||||
} else if minutes > 0 {
|
||||
format!("{minutes}m {seconds}s")
|
||||
} else {
|
||||
format!("{seconds}s")
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove peer(s) by (underlay) IP
|
||||
pub async fn remove_peers(
|
||||
server_addr: SocketAddr,
|
||||
|
||||
@@ -27,7 +27,7 @@ use std::{collections::hash_map::Entry, future::IntoFuture};
|
||||
use tokio::net::TcpStream;
|
||||
use tokio::net::{TcpListener, UdpSocket};
|
||||
use tokio::task::AbortHandle;
|
||||
use tokio::time::MissedTickBehavior;
|
||||
use tokio::time::{Instant, MissedTickBehavior};
|
||||
use tracing::{debug, error, info, instrument, trace, warn};
|
||||
|
||||
/// Magic bytes to identify a multicast UDP packet used in link local peer discovery.
|
||||
@@ -88,6 +88,10 @@ struct PeerInfo {
|
||||
connection_attempts: usize,
|
||||
/// Keep track of the amount of bytes we've sent to and received from this peer.
|
||||
con_traffic: ConnectionTraffic,
|
||||
/// The moment in time we learned about this peer.
|
||||
discovered: Instant,
|
||||
/// The moment we last connected to this peer.
|
||||
connected: Option<Instant>,
|
||||
}
|
||||
|
||||
/// Counters for the amount of traffic written to and received from a [`Peer`].
|
||||
@@ -126,6 +130,10 @@ pub struct PeerStats {
|
||||
pub tx_bytes: u64,
|
||||
/// Amount of bytes received from this [`Peer`].
|
||||
pub rx_bytes: u64,
|
||||
/// Amount of time which passed since the system learned about this [`Peer`], in seconds.
|
||||
pub discovered: u64,
|
||||
/// Amount of seconds since the last succesfull connection to this [`Peer`].
|
||||
pub last_connected: Option<u64>,
|
||||
}
|
||||
|
||||
impl PeerInfo {
|
||||
@@ -212,6 +220,7 @@ where
|
||||
// loop will perform the actual check and figure out they are dead, then
|
||||
// (re)connect.
|
||||
.map(|s| {
|
||||
let now = tokio::time::Instant::now();
|
||||
(
|
||||
s,
|
||||
PeerInfo {
|
||||
@@ -223,6 +232,8 @@ where
|
||||
tx_bytes: Arc::new(AtomicU64::new(0)),
|
||||
rx_bytes: Arc::new(AtomicU64::new(0)),
|
||||
},
|
||||
discovered: now,
|
||||
connected: None,
|
||||
},
|
||||
)
|
||||
})
|
||||
@@ -281,6 +292,7 @@ where
|
||||
if peer_map.contains_key(&peer) {
|
||||
return Err(PeerExists);
|
||||
}
|
||||
let now = tokio::time::Instant::now();
|
||||
peer_map.insert(
|
||||
peer,
|
||||
PeerInfo {
|
||||
@@ -292,6 +304,8 @@ where
|
||||
tx_bytes: Arc::new(AtomicU64::new(0)),
|
||||
rx_bytes: Arc::new(AtomicU64::new(0)),
|
||||
},
|
||||
discovered: now,
|
||||
connected: None,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -333,6 +347,8 @@ where
|
||||
connection_state,
|
||||
tx_bytes: peer_info.written(),
|
||||
rx_bytes: peer_info.read(),
|
||||
discovered: peer_info.discovered.elapsed().as_secs(),
|
||||
last_connected: peer_info.connected.map(|i| i.elapsed().as_secs()),
|
||||
});
|
||||
}
|
||||
pi
|
||||
@@ -382,6 +398,7 @@ where
|
||||
|
||||
// We successfully connected, reset the connection_attempts counter to 0
|
||||
pi.connection_attempts = 0;
|
||||
pi.connected = Some(tokio::time::Instant::now());
|
||||
} else {
|
||||
// Only log with error level on the first connection failure, to avoid spamming the logs
|
||||
if pi.connection_attempts == 0 {
|
||||
@@ -916,6 +933,7 @@ where
|
||||
}
|
||||
}
|
||||
// Only if we don't know it yet.
|
||||
let now = tokio::time::Instant::now();
|
||||
if let Entry::Vacant(e) = peers.entry(endpoint) {
|
||||
e.insert(PeerInfo {
|
||||
pt: discovery_type,
|
||||
@@ -927,6 +945,8 @@ where
|
||||
},
|
||||
connection_attempts: 0,
|
||||
con_traffic,
|
||||
discovered: now,
|
||||
connected: if peer.is_some() { Some(now) } else { None },
|
||||
});
|
||||
if let Some(p) = peer {
|
||||
self.router.lock().unwrap().add_peer_interface(p);
|
||||
@@ -936,6 +956,10 @@ where
|
||||
// We got an inbound peer with a duplicate entry. This is possible if the sending port
|
||||
// is the same as the previous one, which generally happens with our Quic setup. In
|
||||
// this case, the old connection needs to be replaced.
|
||||
let discovered = peers
|
||||
.get(&endpoint)
|
||||
.map(|epi| epi.discovered)
|
||||
.unwrap_or(now);
|
||||
let old_peer_info = peers.insert(
|
||||
endpoint,
|
||||
PeerInfo {
|
||||
@@ -948,6 +972,8 @@ where
|
||||
},
|
||||
connection_attempts: 0,
|
||||
con_traffic,
|
||||
discovered,
|
||||
connected: Some(now),
|
||||
},
|
||||
);
|
||||
// If we have a new peer notify insert the new one in the router, then notify it that
|
||||
|
||||
Reference in new issue
Block a user