stats_accounting
This commit is contained in:
parent
babe176747
commit
3888a832a0
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -25,3 +25,6 @@
|
||||
[submodule "external/mdns"]
|
||||
path = external/mdns
|
||||
url = ../mdns.git
|
||||
[submodule "external/hashlink"]
|
||||
path = external/hashlink
|
||||
url = ../hashlink.git
|
||||
|
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -4201,6 +4201,7 @@ dependencies = [
|
||||
"generic-array 0.14.5",
|
||||
"getrandom 0.2.5",
|
||||
"hashbrown 0.12.0",
|
||||
"hashlink",
|
||||
"hex",
|
||||
"ifstructs",
|
||||
"jni",
|
||||
|
1
external/hashlink
vendored
Submodule
1
external/hashlink
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit f5846ec3ff06865a204114bd710253e7e67e4498
|
@ -26,6 +26,7 @@ generic-array = "^0"
|
||||
secrecy = "^0"
|
||||
chacha20poly1305 = "^0"
|
||||
uluru = "^3"
|
||||
hashlink = "^0"
|
||||
serde-big-array = "^0"
|
||||
futures-util = { version = "^0", default_features = false, features = ["alloc"] }
|
||||
parking_lot = "^0"
|
||||
|
@ -4,8 +4,8 @@ use crate::network_connection::*;
|
||||
use crate::network_manager::*;
|
||||
use crate::xx::*;
|
||||
use crate::*;
|
||||
use futures_util::future::{select, Either};
|
||||
use futures_util::stream::{FuturesUnordered, StreamExt};
|
||||
use futures_util::{select, FutureExt};
|
||||
|
||||
const CONNECTION_PROCESSOR_CHANNEL_SIZE: usize = 128usize;
|
||||
|
||||
@ -162,14 +162,30 @@ impl ConnectionManager {
|
||||
Box::pin(async move {
|
||||
//
|
||||
let descriptor = conn.connection_descriptor();
|
||||
let inactivity_timeout = this
|
||||
.network_manager()
|
||||
.config()
|
||||
.get()
|
||||
.network
|
||||
.connection_inactivity_timeout_ms;
|
||||
loop {
|
||||
let res = conn.clone().recv().await;
|
||||
let message = match res {
|
||||
// process inactivity timeout on receives only
|
||||
// if you want a keepalive, it has to be requested from the other side
|
||||
let message = select! {
|
||||
res = conn.recv().fuse() => {
|
||||
match res {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
log_net!(error e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ = intf::sleep(inactivity_timeout).fuse()=> {
|
||||
// timeout
|
||||
log_net!("connection timeout on {:?}", descriptor);
|
||||
break;
|
||||
}
|
||||
};
|
||||
if let Err(e) = network_manager
|
||||
.on_recv_envelope(message.as_slice(), descriptor)
|
||||
@ -201,8 +217,8 @@ impl ConnectionManager {
|
||||
FuturesUnordered::new();
|
||||
loop {
|
||||
// Either process an existing connection, or receive a new one to add to our list
|
||||
match select(connection_futures.next(), Box::pin(rx.recv_async())).await {
|
||||
Either::Left((x, _)) => {
|
||||
select! {
|
||||
x = connection_futures.next().fuse() => {
|
||||
// Processed some connection to completion, or there are none left
|
||||
match x {
|
||||
Some(()) => {
|
||||
@ -222,7 +238,7 @@ impl ConnectionManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
Either::Right((x, _)) => {
|
||||
x = rx.recv_async().fuse() => {
|
||||
// Got a new connection future
|
||||
match x {
|
||||
Ok(v) => {
|
||||
|
@ -8,7 +8,6 @@ use core::convert::TryInto;
|
||||
use curve25519_dalek as cd;
|
||||
use ed25519_dalek as ed;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_big_array::*;
|
||||
use uluru;
|
||||
use x25519_dalek as xd;
|
||||
|
||||
@ -18,11 +17,6 @@ pub type Nonce = [u8; 24];
|
||||
const DH_CACHE_SIZE: usize = 1024;
|
||||
pub const ENCRYPTION_OVERHEAD: usize = 16;
|
||||
|
||||
big_array! {
|
||||
BigArray;
|
||||
DH_CACHE_SIZE
|
||||
}
|
||||
|
||||
type DHCache = uluru::LRUCache<DHCacheEntry, DH_CACHE_SIZE>;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
|
@ -55,16 +55,21 @@ impl DummyNetworkConnection {
|
||||
///////////////////////////////////////////////////////////
|
||||
// Top-level protocol independent network connection object
|
||||
|
||||
#[derive(Debug)]
|
||||
struct NetworkConnectionInner {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NetworkConnectionStats {
|
||||
last_message_sent_time: Option<u64>,
|
||||
last_message_recv_time: Option<u64>,
|
||||
established_time: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct NetworkConnectionInner {
|
||||
stats: NetworkConnectionStats,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct NetworkConnectionArc {
|
||||
descriptor: ConnectionDescriptor,
|
||||
established_time: u64,
|
||||
protocol_connection: ProtocolNetworkConnection,
|
||||
inner: Mutex<NetworkConnectionInner>,
|
||||
}
|
||||
@ -84,8 +89,11 @@ impl Eq for NetworkConnection {}
|
||||
impl NetworkConnection {
|
||||
fn new_inner() -> NetworkConnectionInner {
|
||||
NetworkConnectionInner {
|
||||
stats: NetworkConnectionStats {
|
||||
last_message_sent_time: None,
|
||||
last_message_recv_time: None,
|
||||
established_time: intf::get_timestamp(),
|
||||
},
|
||||
}
|
||||
}
|
||||
fn new_arc(
|
||||
@ -94,7 +102,6 @@ impl NetworkConnection {
|
||||
) -> NetworkConnectionArc {
|
||||
NetworkConnectionArc {
|
||||
descriptor,
|
||||
established_time: intf::get_timestamp(),
|
||||
protocol_connection,
|
||||
inner: Mutex::new(Self::new_inner()),
|
||||
}
|
||||
@ -136,7 +143,7 @@ impl NetworkConnection {
|
||||
let out = self.arc.protocol_connection.send(message).await;
|
||||
if out.is_ok() {
|
||||
let mut inner = self.arc.inner.lock();
|
||||
inner.last_message_sent_time.max_assign(Some(ts));
|
||||
inner.stats.last_message_sent_time.max_assign(Some(ts));
|
||||
}
|
||||
out
|
||||
}
|
||||
@ -145,8 +152,13 @@ impl NetworkConnection {
|
||||
let out = self.arc.protocol_connection.recv().await;
|
||||
if out.is_ok() {
|
||||
let mut inner = self.arc.inner.lock();
|
||||
inner.last_message_recv_time.max_assign(Some(ts));
|
||||
inner.stats.last_message_recv_time.max_assign(Some(ts));
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
pub fn stats(&self) -> NetworkConnectionStats {
|
||||
let inner = self.arc.inner.lock();
|
||||
inner.stats.clone()
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ use xx::*;
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub const MAX_MESSAGE_SIZE: usize = MAX_ENVELOPE_SIZE;
|
||||
pub const IPADDR_TABLE_SIZE: usize = 1024;
|
||||
pub const IPADDR_MAX_INACTIVE_DURATION_US: u64 = 300_000_000u64; // 5 minutes
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub enum NetworkClass {
|
||||
@ -79,11 +81,33 @@ struct NetworkComponents {
|
||||
receipt_manager: ReceiptManager,
|
||||
}
|
||||
|
||||
// Statistics per address
|
||||
#[derive(Clone, Default)]
|
||||
pub struct PerAddressStats {
|
||||
last_seen_ts: u64,
|
||||
transfer_stats_accounting: TransferStatsAccounting,
|
||||
transfer_stats: TransferStatsDownUp,
|
||||
}
|
||||
|
||||
// Statistics about the low-level network
|
||||
#[derive(Clone, Default)]
|
||||
pub struct NetworkManagerStats {
|
||||
self_stats: PerAddressStats,
|
||||
per_address_stats: HashMap<IpAddr, PerAddressStats>,
|
||||
recent_addresses: VecDeque<IpAddr>,
|
||||
}
|
||||
|
||||
// The mutable state of the network manager
|
||||
pub struct NetworkManagerInner {
|
||||
struct NetworkManagerInner {
|
||||
routing_table: Option<RoutingTable>,
|
||||
components: Option<NetworkComponents>,
|
||||
network_class: Option<NetworkClass>,
|
||||
stats: NetworkManagerStats,
|
||||
}
|
||||
|
||||
struct NetworkManagerUnlockedInner {
|
||||
// Background processes
|
||||
rolling_transfers_task: TickTask,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -92,6 +116,7 @@ pub struct NetworkManager {
|
||||
table_store: TableStore,
|
||||
crypto: Crypto,
|
||||
inner: Arc<Mutex<NetworkManagerInner>>,
|
||||
unlocked_inner: Arc<NetworkManagerUnlockedInner>,
|
||||
}
|
||||
|
||||
impl NetworkManager {
|
||||
@ -100,16 +125,34 @@ impl NetworkManager {
|
||||
routing_table: None,
|
||||
components: None,
|
||||
network_class: None,
|
||||
stats: NetworkManagerStats::default(),
|
||||
}
|
||||
}
|
||||
fn new_unlocked_inner(_config: VeilidConfig) -> NetworkManagerUnlockedInner {
|
||||
//let c = config.get();
|
||||
NetworkManagerUnlockedInner {
|
||||
rolling_transfers_task: TickTask::new(ROLLING_TRANSFERS_INTERVAL_SECS),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(config: VeilidConfig, table_store: TableStore, crypto: Crypto) -> Self {
|
||||
Self {
|
||||
config,
|
||||
let this = Self {
|
||||
config: config.clone(),
|
||||
table_store,
|
||||
crypto,
|
||||
inner: Arc::new(Mutex::new(Self::new_inner())),
|
||||
unlocked_inner: Arc::new(Self::new_unlocked_inner(config)),
|
||||
};
|
||||
// Set rolling transfers tick task
|
||||
{
|
||||
let this2 = this.clone();
|
||||
this.unlocked_inner
|
||||
.rolling_transfers_task
|
||||
.set_routine(move |l, t| {
|
||||
Box::pin(this2.clone().rolling_transfers_task_routine(l, t))
|
||||
});
|
||||
}
|
||||
this
|
||||
}
|
||||
pub fn config(&self) -> VeilidConfig {
|
||||
self.config.clone()
|
||||
@ -546,4 +589,76 @@ impl NetworkManager {
|
||||
// Inform caller that we dealt with the envelope locally
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
// Compute transfer statistics for the low level network
|
||||
async fn rolling_transfers_task_routine(self, last_ts: u64, cur_ts: u64) -> Result<(), String> {
|
||||
log_net!("--- network manager rolling_transfers task");
|
||||
let inner = &mut *self.inner.lock();
|
||||
|
||||
// Roll the low level network transfer stats for our address
|
||||
inner
|
||||
.stats
|
||||
.self_stats
|
||||
.transfer_stats_accounting
|
||||
.roll_transfers(last_ts, cur_ts, &mut inner.stats.self_stats.transfer_stats);
|
||||
|
||||
// Roll all per-address transfers
|
||||
let mut dead_addrs: HashSet<IpAddr> = HashSet::new();
|
||||
for (addr, stats) in &mut inner.stats.per_address_stats {
|
||||
stats.transfer_stats_accounting.roll_transfers(
|
||||
last_ts,
|
||||
cur_ts,
|
||||
&mut stats.transfer_stats,
|
||||
);
|
||||
|
||||
// While we're here, lets see if this address has timed out
|
||||
if cur_ts - stats.last_seen_ts >= IPADDR_MAX_INACTIVE_DURATION_US {
|
||||
// it's dead, put it in the dead list
|
||||
dead_addrs.insert(*addr);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the dead addresses from our tables
|
||||
for da in &dead_addrs {
|
||||
inner.stats.per_address_stats.remove(da);
|
||||
}
|
||||
inner
|
||||
.stats
|
||||
.recent_addresses
|
||||
.retain(|a| !dead_addrs.contains(a));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Callbacks from low level network for statistics gathering
|
||||
fn packet_sent(&self, addr: IpAddr, bytes: u64) {
|
||||
let inner = &mut *self.inner.lock();
|
||||
inner
|
||||
.stats
|
||||
.self_stats
|
||||
.transfer_stats_accounting
|
||||
.add_up(bytes);
|
||||
inner
|
||||
.stats
|
||||
.per_address_stats
|
||||
.entry(addr)
|
||||
.or_default()
|
||||
.transfer_stats_accounting
|
||||
.add_up(bytes);
|
||||
}
|
||||
|
||||
fn packet_rcvd(&self, addr: IpAddr, bytes: u64) {
|
||||
let inner = &mut *self.inner.lock();
|
||||
inner
|
||||
.stats
|
||||
.self_stats
|
||||
.transfer_stats_accounting
|
||||
.add_down(bytes);
|
||||
inner
|
||||
.stats
|
||||
.per_address_stats
|
||||
.entry(addr)
|
||||
.or_default()
|
||||
.transfer_stats_accounting
|
||||
.add_down(bytes);
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,8 @@ pub struct BucketEntry {
|
||||
min_max_version: Option<(u8, u8)>,
|
||||
last_connection: Option<(ConnectionDescriptor, u64)>,
|
||||
dial_infos: Vec<DialInfo>,
|
||||
stats_accounting: StatsAccounting,
|
||||
latency_stats_accounting: LatencyStatsAccounting,
|
||||
transfer_stats_accounting: TransferStatsAccounting,
|
||||
peer_stats: PeerStats,
|
||||
}
|
||||
|
||||
@ -44,7 +45,8 @@ impl BucketEntry {
|
||||
min_max_version: None,
|
||||
last_connection: None,
|
||||
dial_infos: Vec::new(),
|
||||
stats_accounting: StatsAccounting::new(),
|
||||
latency_stats_accounting: LatencyStatsAccounting::new(),
|
||||
transfer_stats_accounting: TransferStatsAccounting::new(),
|
||||
peer_stats: PeerStats {
|
||||
time_added: now,
|
||||
last_seen: None,
|
||||
@ -133,13 +135,16 @@ impl BucketEntry {
|
||||
///// stats methods
|
||||
// called every ROLLING_TRANSFERS_INTERVAL_SECS seconds
|
||||
pub(super) fn roll_transfers(&mut self, last_ts: u64, cur_ts: u64) {
|
||||
self.stats_accounting
|
||||
.roll_transfers(last_ts, cur_ts, &mut self.peer_stats.transfer);
|
||||
self.transfer_stats_accounting.roll_transfers(
|
||||
last_ts,
|
||||
cur_ts,
|
||||
&mut self.peer_stats.transfer,
|
||||
);
|
||||
}
|
||||
|
||||
// Called for every round trip packet we receive
|
||||
fn record_latency(&mut self, latency: u64) {
|
||||
self.peer_stats.latency = Some(self.stats_accounting.record_latency(latency));
|
||||
self.peer_stats.latency = Some(self.latency_stats_accounting.record_latency(latency));
|
||||
}
|
||||
|
||||
///// state machine handling
|
||||
@ -255,7 +260,7 @@ impl BucketEntry {
|
||||
|
||||
pub(super) fn ping_sent(&mut self, ts: u64, bytes: u64) {
|
||||
self.peer_stats.ping_stats.total_sent += 1;
|
||||
self.stats_accounting.add_up(bytes);
|
||||
self.transfer_stats_accounting.add_up(bytes);
|
||||
self.peer_stats.ping_stats.in_flight += 1;
|
||||
self.peer_stats.ping_stats.last_pinged = Some(ts);
|
||||
// if we haven't heard from this node yet and it's our first attempt at contacting it
|
||||
@ -265,14 +270,14 @@ impl BucketEntry {
|
||||
}
|
||||
}
|
||||
pub(super) fn ping_rcvd(&mut self, ts: u64, bytes: u64) {
|
||||
self.stats_accounting.add_down(bytes);
|
||||
self.transfer_stats_accounting.add_down(bytes);
|
||||
self.touch_last_seen(ts);
|
||||
}
|
||||
pub(super) fn pong_sent(&mut self, _ts: u64, bytes: u64) {
|
||||
self.stats_accounting.add_up(bytes);
|
||||
self.transfer_stats_accounting.add_up(bytes);
|
||||
}
|
||||
pub(super) fn pong_rcvd(&mut self, send_ts: u64, recv_ts: u64, bytes: u64) {
|
||||
self.stats_accounting.add_down(bytes);
|
||||
self.transfer_stats_accounting.add_down(bytes);
|
||||
self.peer_stats.ping_stats.in_flight -= 1;
|
||||
self.peer_stats.ping_stats.total_returned += 1;
|
||||
self.peer_stats.ping_stats.consecutive_pongs += 1;
|
||||
@ -294,7 +299,7 @@ impl BucketEntry {
|
||||
self.peer_stats.ping_stats.first_consecutive_pong_time = None;
|
||||
}
|
||||
pub(super) fn question_sent(&mut self, ts: u64, bytes: u64) {
|
||||
self.stats_accounting.add_up(bytes);
|
||||
self.transfer_stats_accounting.add_up(bytes);
|
||||
// if we haven't heard from this node yet and it's our first attempt at contacting it
|
||||
// then we set the last_seen time
|
||||
if self.peer_stats.last_seen.is_none() {
|
||||
@ -302,14 +307,14 @@ impl BucketEntry {
|
||||
}
|
||||
}
|
||||
pub(super) fn question_rcvd(&mut self, ts: u64, bytes: u64) {
|
||||
self.stats_accounting.add_down(bytes);
|
||||
self.transfer_stats_accounting.add_down(bytes);
|
||||
self.touch_last_seen(ts);
|
||||
}
|
||||
pub(super) fn answer_sent(&mut self, _ts: u64, bytes: u64) {
|
||||
self.stats_accounting.add_up(bytes);
|
||||
self.transfer_stats_accounting.add_up(bytes);
|
||||
}
|
||||
pub(super) fn answer_rcvd(&mut self, send_ts: u64, recv_ts: u64, bytes: u64) {
|
||||
self.stats_accounting.add_down(bytes);
|
||||
self.transfer_stats_accounting.add_down(bytes);
|
||||
self.record_latency(recv_ts - send_ts);
|
||||
self.touch_last_seen(recv_ts);
|
||||
}
|
||||
|
@ -7,8 +7,14 @@ impl RoutingTable {
|
||||
out += "Routing Table Info:\n";
|
||||
|
||||
out += &format!(" Node Id: {}\n", inner.node_id.encode());
|
||||
out += &format!(" Stats Accounting: {:#?}\n\n", inner.stats_accounting);
|
||||
out += &format!(" Transfer Stats: {:#?}\n\n", inner.transfer_stats);
|
||||
out += &format!(
|
||||
" Self Transfer Stats Accounting: {:#?}\n\n",
|
||||
inner.self_transfer_stats_accounting
|
||||
);
|
||||
out += &format!(
|
||||
" Self Transfer Stats: {:#?}\n\n",
|
||||
inner.self_transfer_stats
|
||||
);
|
||||
|
||||
out
|
||||
}
|
||||
|
@ -50,12 +50,14 @@ struct RoutingTableInner {
|
||||
buckets: Vec<Bucket>,
|
||||
dial_info_details: Vec<DialInfoDetail>,
|
||||
bucket_entry_count: usize,
|
||||
|
||||
// Waiters
|
||||
eventual_changed_dial_info: Eventual,
|
||||
|
||||
// Transfer stats for this node
|
||||
stats_accounting: StatsAccounting,
|
||||
// latency: Option<LatencyStats>,
|
||||
transfer_stats: TransferStatsDownUp,
|
||||
self_latency_stats_accounting: LatencyStatsAccounting,
|
||||
self_transfer_stats_accounting: TransferStatsAccounting,
|
||||
self_transfer_stats: TransferStatsDownUp,
|
||||
}
|
||||
|
||||
struct RoutingTableUnlockedInner {
|
||||
@ -83,8 +85,9 @@ impl RoutingTable {
|
||||
dial_info_details: Vec::new(),
|
||||
bucket_entry_count: 0,
|
||||
eventual_changed_dial_info: Eventual::new(),
|
||||
stats_accounting: StatsAccounting::new(),
|
||||
transfer_stats: TransferStatsDownUp::default(),
|
||||
self_latency_stats_accounting: LatencyStatsAccounting::new(),
|
||||
self_transfer_stats_accounting: TransferStatsAccounting::new(),
|
||||
self_transfer_stats: TransferStatsDownUp::default(),
|
||||
}
|
||||
}
|
||||
fn new_unlocked_inner(config: VeilidConfig) -> RoutingTableUnlockedInner {
|
||||
@ -609,9 +612,11 @@ impl RoutingTable {
|
||||
let inner = &mut *self.inner.lock();
|
||||
|
||||
// Roll our own node's transfers
|
||||
inner
|
||||
.stats_accounting
|
||||
.roll_transfers(last_ts, cur_ts, &mut inner.transfer_stats);
|
||||
inner.self_transfer_stats_accounting.roll_transfers(
|
||||
last_ts,
|
||||
cur_ts,
|
||||
&mut inner.self_transfer_stats,
|
||||
);
|
||||
|
||||
// Roll all bucket entry transfers
|
||||
for b in &mut inner.buckets {
|
||||
@ -649,25 +654,37 @@ impl RoutingTable {
|
||||
// Stats Accounting
|
||||
|
||||
pub fn ping_sent(&self, node_ref: NodeRef, ts: u64, bytes: u64) {
|
||||
self.inner.lock().stats_accounting.add_up(bytes);
|
||||
self.inner
|
||||
.lock()
|
||||
.self_transfer_stats_accounting
|
||||
.add_up(bytes);
|
||||
node_ref.operate(|e| {
|
||||
e.ping_sent(ts, bytes);
|
||||
})
|
||||
}
|
||||
pub fn ping_rcvd(&self, node_ref: NodeRef, ts: u64, bytes: u64) {
|
||||
self.inner.lock().stats_accounting.add_down(bytes);
|
||||
self.inner
|
||||
.lock()
|
||||
.self_transfer_stats_accounting
|
||||
.add_down(bytes);
|
||||
node_ref.operate(|e| {
|
||||
e.ping_rcvd(ts, bytes);
|
||||
})
|
||||
}
|
||||
pub fn pong_sent(&self, node_ref: NodeRef, ts: u64, bytes: u64) {
|
||||
self.inner.lock().stats_accounting.add_up(bytes);
|
||||
self.inner
|
||||
.lock()
|
||||
.self_transfer_stats_accounting
|
||||
.add_up(bytes);
|
||||
node_ref.operate(|e| {
|
||||
e.pong_sent(ts, bytes);
|
||||
})
|
||||
}
|
||||
pub fn pong_rcvd(&self, node_ref: NodeRef, send_ts: u64, recv_ts: u64, bytes: u64) {
|
||||
self.inner.lock().stats_accounting.add_down(bytes);
|
||||
self.inner
|
||||
.lock()
|
||||
.self_transfer_stats_accounting
|
||||
.add_down(bytes);
|
||||
node_ref.operate(|e| {
|
||||
e.pong_rcvd(send_ts, recv_ts, bytes);
|
||||
})
|
||||
@ -678,25 +695,37 @@ impl RoutingTable {
|
||||
})
|
||||
}
|
||||
pub fn question_sent(&self, node_ref: NodeRef, ts: u64, bytes: u64) {
|
||||
self.inner.lock().stats_accounting.add_up(bytes);
|
||||
self.inner
|
||||
.lock()
|
||||
.self_transfer_stats_accounting
|
||||
.add_up(bytes);
|
||||
node_ref.operate(|e| {
|
||||
e.question_sent(ts, bytes);
|
||||
})
|
||||
}
|
||||
pub fn question_rcvd(&self, node_ref: NodeRef, ts: u64, bytes: u64) {
|
||||
self.inner.lock().stats_accounting.add_down(bytes);
|
||||
self.inner
|
||||
.lock()
|
||||
.self_transfer_stats_accounting
|
||||
.add_down(bytes);
|
||||
node_ref.operate(|e| {
|
||||
e.question_rcvd(ts, bytes);
|
||||
})
|
||||
}
|
||||
pub fn answer_sent(&self, node_ref: NodeRef, ts: u64, bytes: u64) {
|
||||
self.inner.lock().stats_accounting.add_up(bytes);
|
||||
self.inner
|
||||
.lock()
|
||||
.self_transfer_stats_accounting
|
||||
.add_up(bytes);
|
||||
node_ref.operate(|e| {
|
||||
e.answer_sent(ts, bytes);
|
||||
})
|
||||
}
|
||||
pub fn answer_rcvd(&self, node_ref: NodeRef, send_ts: u64, recv_ts: u64, bytes: u64) {
|
||||
self.inner.lock().stats_accounting.add_down(bytes);
|
||||
self.inner
|
||||
.lock()
|
||||
.self_transfer_stats_accounting
|
||||
.add_down(bytes);
|
||||
node_ref.operate(|e| {
|
||||
e.answer_rcvd(send_ts, recv_ts, bytes);
|
||||
})
|
||||
|
@ -19,16 +19,14 @@ pub struct TransferCount {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct StatsAccounting {
|
||||
rolling_latencies: VecDeque<u64>,
|
||||
pub struct TransferStatsAccounting {
|
||||
rolling_transfers: VecDeque<TransferCount>,
|
||||
current_transfer: TransferCount,
|
||||
}
|
||||
|
||||
impl StatsAccounting {
|
||||
impl TransferStatsAccounting {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
rolling_latencies: VecDeque::new(),
|
||||
rolling_transfers: VecDeque::new(),
|
||||
current_transfer: TransferCount::default(),
|
||||
}
|
||||
@ -79,6 +77,19 @@ impl StatsAccounting {
|
||||
transfer_stats.down.average /= len;
|
||||
transfer_stats.up.average /= len;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct LatencyStatsAccounting {
|
||||
rolling_latencies: VecDeque<u64>,
|
||||
}
|
||||
|
||||
impl LatencyStatsAccounting {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
rolling_latencies: VecDeque::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn record_latency(&mut self, latency: u64) -> veilid_api::LatencyStats {
|
||||
while self.rolling_latencies.len() >= ROLLING_LATENCIES_SIZE {
|
||||
|
@ -187,6 +187,7 @@ fn config_callback(key: String) -> ConfigCallbackReturn {
|
||||
"protected_store.delete" => Ok(Box::new(false)),
|
||||
"network.max_connections" => Ok(Box::new(16u32)),
|
||||
"network.connection_initial_timeout_ms" => Ok(Box::new(2_000u32)),
|
||||
"network.connection_inactivity_timeout_ms" => Ok(Box::new(60_000u32)),
|
||||
"network.node_id" => Ok(Box::new(dht::key::DHTKey::default())),
|
||||
"network.node_id_secret" => Ok(Box::new(dht::key::DHTKeySecret::default())),
|
||||
"network.bootstrap" => Ok(Box::new(Vec::<String>::new())),
|
||||
@ -291,6 +292,7 @@ pub async fn test_config() {
|
||||
assert_eq!(inner.protected_store.delete, false);
|
||||
assert_eq!(inner.network.max_connections, 16);
|
||||
assert_eq!(inner.network.connection_initial_timeout_ms, 2_000u32);
|
||||
assert_eq!(inner.network.connection_inactivity_timeout_ms, 60_000u32);
|
||||
assert!(!inner.network.node_id.valid);
|
||||
assert!(!inner.network.node_id_secret.valid);
|
||||
assert_eq!(inner.network.bootstrap, Vec::<String>::new());
|
||||
|
@ -880,12 +880,6 @@ pub struct LatencyStats {
|
||||
pub slowest: u64, // slowest latency in the ROLLING_LATENCIES_SIZE last latencies
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||
pub struct TransferStatsDownUp {
|
||||
pub down: TransferStats,
|
||||
pub up: TransferStats,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||
pub struct TransferStats {
|
||||
pub total: u64, // total amount transferred ever
|
||||
@ -894,6 +888,12 @@ pub struct TransferStats {
|
||||
pub minimum: u64, // minimum rate over the ROLLING_TRANSFERS_SIZE last amounts
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||
pub struct TransferStatsDownUp {
|
||||
pub down: TransferStats,
|
||||
pub up: TransferStats,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||
pub struct PingStats {
|
||||
pub in_flight: u32, // number of pings issued that have yet to be answered
|
||||
|
@ -128,6 +128,7 @@ pub struct VeilidConfigLeases {
|
||||
pub struct VeilidConfigNetwork {
|
||||
pub max_connections: u32,
|
||||
pub connection_initial_timeout_ms: u32,
|
||||
pub connection_inactivity_timeout_ms: u32,
|
||||
pub node_id: key::DHTKey,
|
||||
pub node_id_secret: key::DHTKeySecret,
|
||||
pub bootstrap: Vec<String>,
|
||||
@ -282,6 +283,7 @@ impl VeilidConfig {
|
||||
get_config!(inner.network.node_id_secret);
|
||||
get_config!(inner.network.max_connections);
|
||||
get_config!(inner.network.connection_initial_timeout_ms);
|
||||
get_config!(inner.network.connection_inactivity_timeout_ms);
|
||||
get_config!(inner.network.bootstrap);
|
||||
get_config!(inner.network.dht.resolve_node_timeout_ms);
|
||||
get_config!(inner.network.dht.resolve_node_count);
|
||||
|
@ -31,8 +31,12 @@ cfg_if! {
|
||||
if #[cfg(target_arch = "wasm32")] {
|
||||
pub use alloc::string::String;
|
||||
pub use alloc::vec::Vec;
|
||||
pub use alloc::collections::LinkedList;
|
||||
pub use alloc::collections::VecDeque;
|
||||
pub use alloc::collections::btree_map::BTreeMap;
|
||||
pub use alloc::collections::btree_set::BTreeSet;
|
||||
pub use hashbrown::hash_map::HashMap;
|
||||
pub use hashbrown::hash_set::HashSet;
|
||||
pub use alloc::boxed::Box;
|
||||
pub use alloc::borrow::{Cow, ToOwned};
|
||||
pub use wasm_bindgen::prelude::*;
|
||||
@ -54,8 +58,12 @@ cfg_if! {
|
||||
} else {
|
||||
pub use std::string::String;
|
||||
pub use std::vec::Vec;
|
||||
pub use std::collections::LinkedList;
|
||||
pub use std::collections::VecDeque;
|
||||
pub use std::collections::btree_map::BTreeMap;
|
||||
pub use std::collections::btree_set::BTreeSet;
|
||||
pub use std::collections::hash_map::HashMap;
|
||||
pub use std::collections::hash_set::HashSet;
|
||||
pub use std::boxed::Box;
|
||||
pub use std::borrow::{Cow, ToOwned};
|
||||
pub use std::cmp;
|
||||
|
@ -40,6 +40,7 @@ Future<VeilidConfig> getDefaultVeilidConfig() async {
|
||||
network: VeilidConfigNetwork(
|
||||
maxConnections: 16,
|
||||
connectionInitialTimeoutMs: 2000,
|
||||
connectionInactivityTimeoutMs: 60000,
|
||||
nodeId: "",
|
||||
nodeIdSecret: "",
|
||||
bootstrap: [],
|
||||
|
@ -516,6 +516,7 @@ class VeilidConfigLeases {
|
||||
class VeilidConfigNetwork {
|
||||
int maxConnections;
|
||||
int connectionInitialTimeoutMs;
|
||||
int connectionInactivityTimeoutMs;
|
||||
String nodeId;
|
||||
String nodeIdSecret;
|
||||
List<String> bootstrap;
|
||||
@ -533,6 +534,7 @@ class VeilidConfigNetwork {
|
||||
VeilidConfigNetwork({
|
||||
required this.maxConnections,
|
||||
required this.connectionInitialTimeoutMs,
|
||||
required this.connectionInactivityTimeoutMs,
|
||||
required this.nodeId,
|
||||
required this.nodeIdSecret,
|
||||
required this.bootstrap,
|
||||
@ -552,6 +554,7 @@ class VeilidConfigNetwork {
|
||||
return {
|
||||
'max_connections': maxConnections,
|
||||
'connection_initial_timeout_ms': connectionInitialTimeoutMs,
|
||||
'connection_inactivity_timeout_ms': connectionInactivityTimeoutMs,
|
||||
'node_id': nodeId,
|
||||
'node_id_secret': nodeIdSecret,
|
||||
'bootstrap': bootstrap,
|
||||
@ -571,6 +574,8 @@ class VeilidConfigNetwork {
|
||||
VeilidConfigNetwork.fromJson(Map<String, dynamic> json)
|
||||
: maxConnections = json['max_connections'],
|
||||
connectionInitialTimeoutMs = json['connection_initial_timeout_ms'],
|
||||
connectionInactivityTimeoutMs =
|
||||
json['connection_inactivity_timeout_ms'],
|
||||
nodeId = json['node_id'],
|
||||
nodeIdSecret = json['node_id_secret'],
|
||||
bootstrap = json['bootstrap'],
|
||||
|
@ -50,6 +50,7 @@ core:
|
||||
network:
|
||||
max_connections: 16
|
||||
connection_initial_timeout_ms: 2000
|
||||
connection_inactivity_timeout_ms: 60000
|
||||
node_id: ''
|
||||
node_id_secret: ''
|
||||
bootstrap: []
|
||||
@ -523,6 +524,7 @@ pub struct Leases {
|
||||
pub struct Network {
|
||||
pub max_connections: u32,
|
||||
pub connection_initial_timeout_ms: u32,
|
||||
pub connection_inactivity_timeout_ms: u32,
|
||||
pub node_id: veilid_core::DHTKey,
|
||||
pub node_id_secret: veilid_core::DHTKeySecret,
|
||||
pub bootstrap: Vec<ParsedNodeDialInfo>,
|
||||
@ -794,6 +796,9 @@ impl Settings {
|
||||
"network.connection_initial_timeout_ms" => {
|
||||
Ok(Box::new(inner.core.network.connection_initial_timeout_ms))
|
||||
}
|
||||
"network.connection_inactivity_timeout_ms" => Ok(Box::new(
|
||||
inner.core.network.connection_inactivity_timeout_ms,
|
||||
)),
|
||||
"network.node_id" => Ok(Box::new(inner.core.network.node_id)),
|
||||
"network.node_id_secret" => Ok(Box::new(inner.core.network.node_id_secret)),
|
||||
"network.bootstrap" => Ok(Box::new(
|
||||
@ -1131,6 +1136,7 @@ mod tests {
|
||||
|
||||
assert_eq!(s.core.network.max_connections, 16);
|
||||
assert_eq!(s.core.network.connection_initial_timeout_ms, 2_000u32);
|
||||
assert_eq!(s.core.network.connection_inactivity_timeout_ms, 60_000u32);
|
||||
assert_eq!(s.core.network.node_id, veilid_core::DHTKey::default());
|
||||
assert_eq!(
|
||||
s.core.network.node_id_secret,
|
||||
|
Loading…
Reference in New Issue
Block a user