aboutsummaryrefslogtreecommitdiffstats
path: root/src/swarm/tree.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-04 19:46:17 +0100
committertv <tv@krebsco.de>2026-11-04 19:46:17 +0100
commitc3faf6ecde8157154a01daa2ddc0ac02e6c761f1 (patch)
treee48db7771a8a6baf8afb4d21063ffe72894f83b0 /src/swarm/tree.rs
parent07ef1e4e562d977e72f0a6b702736ae3645b45c7 (diff)
tree messages need no answer
Diffstat (limited to 'src/swarm/tree.rs')
-rw-r--r--src/swarm/tree.rs20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/swarm/tree.rs b/src/swarm/tree.rs
index b21908e..c474754 100644
--- a/src/swarm/tree.rs
+++ b/src/swarm/tree.rs
@@ -16,9 +16,10 @@
//! pair key here): whoever applies changes passes them on to its own children in each of
//! their writers' trees (`forward`), however they came; so does the writer, to all its
//! neighbours, with its own writes. A sync message along a tree also says whose
-//! (`SyncEnvelope::writer`), for one that had them already (`swarm::sync`). A member no
-//! member it reaches comes before (or whose parent didn't get the change) gets it from
-//! the announcements (`swarm::relay`), as before.
+//! (`SyncEnvelope::writer`), for one that had them already (`swarm::sync`), and needs no
+//! answer where the child had nothing the parent lacks (`SyncSession::assume_delivered`).
+//! A member no member it reaches comes before (or whose parent didn't get the change)
+//! gets it from the announcements (`swarm::relay`), as before.
//!
//! The graph is computed once per member list (tens of milliseconds for thousands of
//! members), the distances once per writer and graph (`MAX_WRITERS` kept).
@@ -176,6 +177,10 @@ pub(crate) fn whole(
/// out (`uncovered`).
pub(crate) struct Plan {
pub(crate) children: Vec<String>,
+ /// Those of our children that reach no member but us, as they said: nobody else's
+ /// slow round tells them of a change, should our message to them be lost (it is
+ /// taken as delivered, `SyncSession::assume_delivered`), so ours does.
+ pub(crate) alone: Vec<String>,
/// Our neighbours that no member they reach comes before (the tree reaches them only
/// by announcement), and those not in the member list's graph (whom no tree has).
pub(crate) uncovered: Vec<String>,
@@ -205,7 +210,9 @@ pub(crate) async fn plan(state: &AppState, writer: u64) -> Option<Plan> {
.is_none_or(|keys| keys.contains(&topology::pair_key(member)))
};
let my_rank = rank(&graph, &distance, &reached, me)?;
+ let my_key = topology::pair_key(me);
let mut children = Vec::new();
+ let mut alone = Vec::new();
let mut uncovered = Vec::new();
for member in graph.get(me).into_iter().flatten() {
let Some(its_rank) = rank(&graph, &distance, &reached, member) else {
@@ -219,6 +226,12 @@ pub(crate) async fn plan(state: &AppState, writer: u64) -> Option<Plan> {
Some(parent)
if parent == me && its_rank > my_rank && topology::reaches(state, member).await =>
{
+ if reaches
+ .get(member.as_str())
+ .is_some_and(|keys| keys.iter().all(|key| *key == my_key))
+ {
+ alone.push(member.clone());
+ }
children.push(member.clone());
}
Some(_) => {}
@@ -235,6 +248,7 @@ pub(crate) async fn plan(state: &AppState, writer: u64) -> Option<Plan> {
}
Some(Plan {
children,
+ alone,
uncovered,
})
}