aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-06 18:28:22 +0100
committertv <tv@krebsco.de>2026-11-06 18:28:22 +0100
commite86a1a3b9b740b65a149622e15c5d8f0f4c557ef (patch)
tree6ec9f2be314d77ceb08c469e855d6d146db25447 /src
parentab8f5447680da56ce658abbc33c222219c3204ef (diff)
bench eager link RTTs
Diffstat (limited to 'src')
-rw-r--r--src/simtest/bench.rs47
1 files changed, 40 insertions, 7 deletions
diff --git a/src/simtest/bench.rs b/src/simtest/bench.rs
index d797115..affdf69 100644
--- a/src/simtest/bench.rs
+++ b/src/simtest/bench.rs
@@ -732,20 +732,49 @@ pub(super) async fn sent_kept(out: &mut String, nodes: &[AppState]) {
);
}
+/// A link with a longer round trip is slow (`eager_links`): over Tor, a slow circuit
+/// (`tor_like`).
+const SLOW_LINK_MS: u64 = 1000;
+
+/// The mean of `values`, rounded; 0 for none.
+fn mean(values: &[u64]) -> u64 {
+ if values.is_empty() {
+ 0
+ } else {
+ values.iter().sum::<u64>() / values.len() as u64
+ }
+}
+
/// PlumTree's links after the workload (`swarm::plumtree`): how many neighbours each
/// node pushes to at once (eager), how many push to it, the nodes none pushes to (they
-/// get every change by announcement and pull), and the links eager at one end only (a
-/// PRUNE or GRAFT lost, or crossing). Nothing for a way that keeps no such links.
+/// get every change by announcement and pull), the links eager at one end only (a
+/// PRUNE or GRAFT lost, or crossing), and the round trips of eager links against lazy
+/// ones (does the tree take slow links?). Nothing for a way that keeps no such links.
fn eager_links(out: &mut String, nodes: &[AppState]) {
let mut pushes: HashMap<String, Vec<String>> = HashMap::new();
+ // The round trips of eager and of lazy links, as each node measured them.
+ let (mut eager_rtts, mut lazy_rtts) = (Vec::new(), Vec::new());
for node in nodes {
let Some(lazy) = node.dissemination.lazy() else {
return;
};
- let eager = crate::swarm::topology::our_neighbours(node)
- .into_iter()
- .filter(|peer| !lazy.contains(peer))
- .collect();
+ let (eager, others): (Vec<String>, Vec<String>) =
+ crate::swarm::topology::our_neighbours(node)
+ .into_iter()
+ .partition(|peer| !lazy.contains(peer));
+ {
+ let rtt = node.lock_rtt();
+ let now = tokio::time::Instant::now();
+ let fresh = node.timing.rtt_fresh_for();
+ for (peers, rtts) in [(&eager, &mut eager_rtts), (&others, &mut lazy_rtts)] {
+ rtts.extend(
+ peers
+ .iter()
+ .filter_map(|peer| rtt.effective(peer, now, fresh))
+ .map(|rtt| rtt.as_millis() as u64),
+ );
+ }
+ }
pushes.insert(node.local_id().to_owned(), eager);
}
let name = |id: &str| {
@@ -781,7 +810,8 @@ fn eager_links(out: &mut String, nodes: &[AppState]) {
let _ = writeln!(
out,
" PlumTree's links at the end: each node pushes to {:.1} neighbours on average; \
- pushed to by {in_least} at least; {} pushed to by none{}; {one_ended} links eager at one end only",
+ pushed to by {in_least} at least; {} pushed to by none{}; {one_ended} links eager at one end only; \
+ round trips of eager links {} ms on average, {} of them over {SLOW_LINK_MS} ms; of lazy links {} ms",
out_sum as f64 / count,
unpushed.len(),
if unpushed.is_empty() {
@@ -789,6 +819,9 @@ fn eager_links(out: &mut String, nodes: &[AppState]) {
} else {
format!(" ({})", unpushed.join(", "))
},
+ mean(&eager_rtts),
+ eager_rtts.iter().filter(|rtt| **rtt > SLOW_LINK_MS).count(),
+ mean(&lazy_rtts),
);
}