node: Track peer latency
This is useful for a bunch of different network optimizations we're going to be working on.
This commit is contained in:
parent
664cf20c92
commit
d6d90c6fdc
|
|
@ -78,6 +78,8 @@ pub const PRUNE_INTERVAL: LocalDuration = LocalDuration::from_mins(30);
|
||||||
pub const STALE_CONNECTION_TIMEOUT: LocalDuration = LocalDuration::from_mins(2);
|
pub const STALE_CONNECTION_TIMEOUT: LocalDuration = LocalDuration::from_mins(2);
|
||||||
/// How much time should pass after a peer was last active for a *ping* to be sent.
|
/// How much time should pass after a peer was last active for a *ping* to be sent.
|
||||||
pub const KEEP_ALIVE_DELTA: LocalDuration = LocalDuration::from_mins(1);
|
pub const KEEP_ALIVE_DELTA: LocalDuration = LocalDuration::from_mins(1);
|
||||||
|
/// Maximum number of latency values to keep for a session.
|
||||||
|
pub const MAX_LATENCIES: usize = 16;
|
||||||
/// Maximum time difference between the local time, and an announcement timestamp.
|
/// Maximum time difference between the local time, and an announcement timestamp.
|
||||||
pub const MAX_TIME_DELTA: LocalDuration = LocalDuration::from_mins(60);
|
pub const MAX_TIME_DELTA: LocalDuration = LocalDuration::from_mins(60);
|
||||||
/// Maximum attempts to connect to a peer before we give up.
|
/// Maximum attempts to connect to a peer before we give up.
|
||||||
|
|
@ -1653,10 +1655,24 @@ where
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
(session::State::Connected { ping, .. }, Message::Pong { zeroes }) => {
|
(
|
||||||
if let session::PingState::AwaitingResponse(ponglen) = *ping {
|
session::State::Connected {
|
||||||
|
ping, latencies, ..
|
||||||
|
},
|
||||||
|
Message::Pong { zeroes },
|
||||||
|
) => {
|
||||||
|
if let session::PingState::AwaitingResponse {
|
||||||
|
len: ponglen,
|
||||||
|
since,
|
||||||
|
} = *ping
|
||||||
|
{
|
||||||
if (ponglen as usize) == zeroes.len() {
|
if (ponglen as usize) == zeroes.len() {
|
||||||
*ping = session::PingState::Ok;
|
*ping = session::PingState::Ok;
|
||||||
|
// Keep track of peer latency.
|
||||||
|
latencies.push_back(self.clock - since);
|
||||||
|
if latencies.len() > MAX_LATENCIES {
|
||||||
|
latencies.pop_front();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2036,7 +2052,7 @@ where
|
||||||
.filter(|(_, session)| *now - session.last_active >= KEEP_ALIVE_DELTA)
|
.filter(|(_, session)| *now - session.last_active >= KEEP_ALIVE_DELTA)
|
||||||
.map(|(_, session)| session);
|
.map(|(_, session)| session);
|
||||||
for session in inactive_sessions {
|
for session in inactive_sessions {
|
||||||
session.ping(&mut self.outbox).ok();
|
session.ping(self.clock, &mut self.outbox).ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::collections::HashSet;
|
use std::collections::{HashSet, VecDeque};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use crate::node::config::Limits;
|
use crate::node::config::Limits;
|
||||||
|
|
@ -119,6 +119,7 @@ impl Session {
|
||||||
since: time,
|
since: time,
|
||||||
ping: PingState::default(),
|
ping: PingState::default(),
|
||||||
fetching: HashSet::default(),
|
fetching: HashSet::default(),
|
||||||
|
latencies: VecDeque::default(),
|
||||||
},
|
},
|
||||||
link: Link::Inbound,
|
link: Link::Inbound,
|
||||||
subscribe: None,
|
subscribe: None,
|
||||||
|
|
@ -212,6 +213,7 @@ impl Session {
|
||||||
since,
|
since,
|
||||||
ping: PingState::default(),
|
ping: PingState::default(),
|
||||||
fetching: HashSet::default(),
|
fetching: HashSet::default(),
|
||||||
|
latencies: VecDeque::default(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -231,11 +233,13 @@ impl Session {
|
||||||
self.state = State::Initial;
|
self.state = State::Initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ping(&mut self, reactor: &mut Outbox) -> Result<(), Error> {
|
pub fn ping(&mut self, since: LocalTime, reactor: &mut Outbox) -> Result<(), Error> {
|
||||||
if let State::Connected { ping, .. } = &mut self.state {
|
if let State::Connected { ping, .. } = &mut self.state {
|
||||||
let msg = message::Ping::new(&mut self.rng);
|
let msg = message::Ping::new(&mut self.rng);
|
||||||
*ping = PingState::AwaitingResponse(msg.ponglen);
|
*ping = PingState::AwaitingResponse {
|
||||||
|
len: msg.ponglen,
|
||||||
|
since,
|
||||||
|
};
|
||||||
reactor.write(self, Message::Ping(msg));
|
reactor.write(self, Message::Ping(msg));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ pub mod policy;
|
||||||
pub mod routing;
|
pub mod routing;
|
||||||
pub mod seed;
|
pub mod seed;
|
||||||
|
|
||||||
use std::collections::{BTreeSet, HashMap, HashSet};
|
use std::collections::{BTreeSet, HashMap, HashSet, VecDeque};
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::ops::{ControlFlow, Deref};
|
use std::ops::{ControlFlow, Deref};
|
||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
|
|
@ -21,7 +21,7 @@ use std::{fmt, io, net, thread, time};
|
||||||
|
|
||||||
use amplify::WrapperMut;
|
use amplify::WrapperMut;
|
||||||
use cyphernet::addr::NetAddr;
|
use cyphernet::addr::NetAddr;
|
||||||
use localtime::LocalTime;
|
use localtime::{LocalDuration, LocalTime};
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json as json;
|
use serde_json as json;
|
||||||
|
|
@ -73,7 +73,12 @@ pub enum PingState {
|
||||||
/// The peer has not been sent a ping.
|
/// The peer has not been sent a ping.
|
||||||
None,
|
None,
|
||||||
/// A ping has been sent and is waiting on the peer's response.
|
/// A ping has been sent and is waiting on the peer's response.
|
||||||
AwaitingResponse(u16),
|
AwaitingResponse {
|
||||||
|
/// Length of pong payload expected.
|
||||||
|
len: u16,
|
||||||
|
/// Since when are we waiting.
|
||||||
|
since: LocalTime,
|
||||||
|
},
|
||||||
/// The peer was successfully pinged.
|
/// The peer was successfully pinged.
|
||||||
Ok,
|
Ok,
|
||||||
}
|
}
|
||||||
|
|
@ -97,6 +102,9 @@ pub enum State {
|
||||||
ping: PingState,
|
ping: PingState,
|
||||||
/// Ongoing fetches.
|
/// Ongoing fetches.
|
||||||
fetching: HashSet<RepoId>,
|
fetching: HashSet<RepoId>,
|
||||||
|
/// Measured latencies for this peer.
|
||||||
|
#[serde(skip)]
|
||||||
|
latencies: VecDeque<LocalDuration>,
|
||||||
},
|
},
|
||||||
/// When a peer is disconnected.
|
/// When a peer is disconnected.
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
|
|
@ -1177,6 +1185,7 @@ mod test {
|
||||||
since: LocalTime::now(),
|
since: LocalTime::now(),
|
||||||
ping: Default::default(),
|
ping: Default::default(),
|
||||||
fetching: Default::default(),
|
fetching: Default::default(),
|
||||||
|
latencies: VecDeque::default(),
|
||||||
}))
|
}))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue