diff --git a/veilid-core/src/routing_table/route_spec_store/mod.rs b/veilid-core/src/routing_table/route_spec_store/mod.rs index 96e509d5..d051122e 100644 --- a/veilid-core/src/routing_table/route_spec_store/mod.rs +++ b/veilid-core/src/routing_table/route_spec_store/mod.rs @@ -915,10 +915,14 @@ impl RouteSpecStore { F: FnMut(&RouteId, &RemotePrivateRouteInfo) -> Option, { let inner = self.inner.lock(); - let mut out = Vec::with_capacity(inner.cache.get_remote_private_route_count()); - for info in inner.cache.iter_remote_private_routes() { - if let Some(x) = filter(info.0, info.1) { - out.push(x); + let cur_ts = get_aligned_timestamp(); + let remote_route_ids = inner.cache.get_remote_private_route_ids(cur_ts); + let mut out = Vec::with_capacity(remote_route_ids.len()); + for id in remote_route_ids { + if let Some(rpri) = inner.cache.peek_remote_private_route(cur_ts, &id) { + if let Some(x) = filter(&id, rpri) { + out.push(x); + } } } out @@ -928,7 +932,7 @@ impl RouteSpecStore { pub fn debug_route(&self, id: &RouteId) -> Option { let inner = &mut *self.inner.lock(); let cur_ts = get_aligned_timestamp(); - if let Some(rpri) = inner.cache.peek_remote_private_route_mut(cur_ts, id) { + if let Some(rpri) = inner.cache.peek_remote_private_route(cur_ts, id) { return Some(format!("{:#?}", rpri)); } if let Some(rssd) = inner.content.get_detail(id) { @@ -1587,7 +1591,7 @@ impl RouteSpecStore { /// Check to see if this remote (not ours) private route has seen our current node info yet /// This happens when you communicate with a private route without a safety route pub fn has_remote_private_route_seen_our_node_info(&self, key: &PublicKey) -> bool { - let inner = &mut *self.inner.lock(); + let inner = &*self.inner.lock(); // Check for local route. If this is not a remote private route, // we may be running a test and using our own local route as the destination private route. @@ -1598,7 +1602,7 @@ impl RouteSpecStore { if let Some(rrid) = inner.cache.get_remote_private_route_id_by_key(key) { let cur_ts = get_aligned_timestamp(); - if let Some(rpri) = inner.cache.peek_remote_private_route_mut(cur_ts, &rrid) { + if let Some(rpri) = inner.cache.peek_remote_private_route(cur_ts, &rrid) { let our_node_info_ts = self .unlocked_inner .routing_table @@ -1646,7 +1650,7 @@ impl RouteSpecStore { } /// Get the route statistics for any route we know about, local or remote - pub fn with_route_stats(&self, cur_ts: Timestamp, key: &PublicKey, f: F) -> Option + pub fn with_route_stats_mut(&self, cur_ts: Timestamp, key: &PublicKey, f: F) -> Option where F: FnOnce(&mut RouteStats) -> R, { diff --git a/veilid-core/src/routing_table/route_spec_store/remote_private_route_info.rs b/veilid-core/src/routing_table/route_spec_store/remote_private_route_info.rs index 2174daa8..6246595b 100644 --- a/veilid-core/src/routing_table/route_spec_store/remote_private_route_info.rs +++ b/veilid-core/src/routing_table/route_spec_store/remote_private_route_info.rs @@ -45,7 +45,7 @@ impl RemotePrivateRouteInfo { &mut self.stats } - pub fn has_seen_our_node_info_ts(&mut self, our_node_info_ts: Timestamp) -> bool { + pub fn has_seen_our_node_info_ts(&self, our_node_info_ts: Timestamp) -> bool { self.last_seen_our_node_info_ts == our_node_info_ts } pub fn set_last_seen_our_node_info_ts(&mut self, last_seen_our_node_info_ts: Timestamp) { diff --git a/veilid-core/src/routing_table/route_spec_store/route_spec_store_cache.rs b/veilid-core/src/routing_table/route_spec_store/route_spec_store_cache.rs index 673ce6d3..35db90a7 100644 --- a/veilid-core/src/routing_table/route_spec_store/route_spec_store_cache.rs +++ b/veilid-core/src/routing_table/route_spec_store/route_spec_store_cache.rs @@ -173,16 +173,18 @@ impl RouteSpecStoreCache { id } - /// get count of remote private routes in cache - pub fn get_remote_private_route_count(&self) -> usize { - self.remote_private_route_set_cache.len() - } - /// iterate all of the remote private routes we have in the cache - pub fn iter_remote_private_routes( - &self, - ) -> hashlink::linked_hash_map::Iter { - self.remote_private_route_set_cache.iter() + pub fn get_remote_private_route_ids(&self, cur_ts: Timestamp) -> Vec { + self.remote_private_route_set_cache + .iter() + .filter_map(|(id, rpri)| { + if !rpri.did_expire(cur_ts) { + Some(*id) + } else { + None + } + }) + .collect() } /// remote private route cache accessor @@ -217,6 +219,21 @@ impl RouteSpecStoreCache { None } + /// remote private route cache accessor without lru action + /// will not LRU entries but may expire entries and not return them if they are stale + pub fn peek_remote_private_route( + &self, + cur_ts: Timestamp, + id: &RouteId, + ) -> Option<&RemotePrivateRouteInfo> { + if let Some(rpri) = self.remote_private_route_set_cache.peek(id) { + if !rpri.did_expire(cur_ts) { + return Some(rpri); + } + } + None + } + /// mutable remote private route cache accessor without lru action /// will not LRU entries but may expire entries and not return them if they are stale pub fn peek_remote_private_route_mut( diff --git a/veilid-core/src/rpc_processor/mod.rs b/veilid-core/src/rpc_processor/mod.rs index cced8b54..c32ba413 100644 --- a/veilid-core/src/rpc_processor/mod.rs +++ b/veilid-core/src/rpc_processor/mod.rs @@ -938,12 +938,12 @@ impl RPCProcessor { // If safety route was in use, record failure to send there if let Some(sr_pubkey) = &safety_route { let rss = self.routing_table.route_spec_store(); - rss.with_route_stats(send_ts, sr_pubkey, |s| s.record_send_failed()); + rss.with_route_stats_mut(send_ts, sr_pubkey, |s| s.record_send_failed()); } else { // If no safety route was in use, then it's the private route's fault if we have one if let Some(pr_pubkey) = &remote_private_route { let rss = self.routing_table.route_spec_store(); - rss.with_route_stats(send_ts, pr_pubkey, |s| s.record_send_failed()); + rss.with_route_stats_mut(send_ts, pr_pubkey, |s| s.record_send_failed()); } } } @@ -972,19 +972,19 @@ impl RPCProcessor { // If safety route was used, record question lost there if let Some(sr_pubkey) = &safety_route { let rss = self.routing_table.route_spec_store(); - rss.with_route_stats(send_ts, sr_pubkey, |s| { + rss.with_route_stats_mut(send_ts, sr_pubkey, |s| { s.record_question_lost(); }); } // If remote private route was used, record question lost there if let Some(rpr_pubkey) = &remote_private_route { - rss.with_route_stats(send_ts, rpr_pubkey, |s| { + rss.with_route_stats_mut(send_ts, rpr_pubkey, |s| { s.record_question_lost(); }); } // If private route was used, record question lost there if let Some(pr_pubkey) = &private_route { - rss.with_route_stats(send_ts, pr_pubkey, |s| { + rss.with_route_stats_mut(send_ts, pr_pubkey, |s| { s.record_question_lost(); }); } @@ -1018,7 +1018,7 @@ impl RPCProcessor { // If safety route was used, record send there if let Some(sr_pubkey) = &safety_route { - rss.with_route_stats(send_ts, sr_pubkey, |s| { + rss.with_route_stats_mut(send_ts, sr_pubkey, |s| { s.record_sent(send_ts, bytes); }); } @@ -1026,7 +1026,7 @@ impl RPCProcessor { // If remote private route was used, record send there if let Some(pr_pubkey) = &remote_private_route { let rss = self.routing_table.route_spec_store(); - rss.with_route_stats(send_ts, pr_pubkey, |s| { + rss.with_route_stats_mut(send_ts, pr_pubkey, |s| { s.record_sent(send_ts, bytes); }); } @@ -1059,7 +1059,7 @@ impl RPCProcessor { // If safety route was used, record route there if let Some(sr_pubkey) = &safety_route { - rss.with_route_stats(send_ts, sr_pubkey, |s| { + rss.with_route_stats_mut(send_ts, sr_pubkey, |s| { // If we received an answer, the safety route we sent over can be considered tested s.record_tested(recv_ts); @@ -1070,7 +1070,7 @@ impl RPCProcessor { // If local private route was used, record route there if let Some(pr_pubkey) = &reply_private_route { - rss.with_route_stats(send_ts, pr_pubkey, |s| { + rss.with_route_stats_mut(send_ts, pr_pubkey, |s| { // Record received bytes s.record_received(recv_ts, bytes); @@ -1081,7 +1081,7 @@ impl RPCProcessor { // If remote private route was used, record there if let Some(rpr_pubkey) = &remote_private_route { - rss.with_route_stats(send_ts, rpr_pubkey, |s| { + rss.with_route_stats_mut(send_ts, rpr_pubkey, |s| { // Record received bytes s.record_received(recv_ts, bytes); @@ -1106,12 +1106,12 @@ impl RPCProcessor { // then we must have received with a local private route too, per the design rules if let Some(sr_pubkey) = &safety_route { let rss = self.routing_table.route_spec_store(); - rss.with_route_stats(send_ts, sr_pubkey, |s| { + rss.with_route_stats_mut(send_ts, sr_pubkey, |s| { s.record_latency(total_latency / 2u64); }); } if let Some(pr_pubkey) = &reply_private_route { - rss.with_route_stats(send_ts, pr_pubkey, |s| { + rss.with_route_stats_mut(send_ts, pr_pubkey, |s| { s.record_latency(total_latency / 2u64); }); } @@ -1137,7 +1137,7 @@ impl RPCProcessor { // This may record nothing if the remote safety route is not also // a remote private route that been imported, but that's okay - rss.with_route_stats(recv_ts, &d.remote_safety_route, |s| { + rss.with_route_stats_mut(recv_ts, &d.remote_safety_route, |s| { s.record_received(recv_ts, bytes); }); } @@ -1149,12 +1149,12 @@ impl RPCProcessor { // a remote private route that been imported, but that's okay // it could also be a node id if no remote safety route was used // in which case this also will do nothing - rss.with_route_stats(recv_ts, &d.remote_safety_route, |s| { + rss.with_route_stats_mut(recv_ts, &d.remote_safety_route, |s| { s.record_received(recv_ts, bytes); }); // Record for our local private route we received over - rss.with_route_stats(recv_ts, &d.private_route, |s| { + rss.with_route_stats_mut(recv_ts, &d.private_route, |s| { s.record_received(recv_ts, bytes); }); } diff --git a/veilid-core/src/veilid_api/debug.rs b/veilid-core/src/veilid_api/debug.rs index 2a771ddc..7596bcc4 100644 --- a/veilid-core/src/veilid_api/debug.rs +++ b/veilid-core/src/veilid_api/debug.rs @@ -1724,6 +1724,7 @@ impl VeilidAPI { parse_duration, ) .ok() + .map(|dur| dur + get_timestamp()) .unwrap_or_else(|| { rest_defaults = true; Default::default()