summaryrefslogtreecommitdiffstats
path: root/src/swarm/topology.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-10-25 22:12:27 +0100
committertv <tv@krebsco.de>2026-10-25 22:12:27 +0100
commit34989e5140eaa16e17a0ab4501e64e779215e3d1 (patch)
tree3a7c5c784d487c3c6069605e4123ab1faa76e452 /src/swarm/topology.rs
parent2d53123f93fe35993f317b00be71c7c8410e635b (diff)
recompute neighbours whenever topology changes
Diffstat (limited to 'src/swarm/topology.rs')
-rw-r--r--src/swarm/topology.rs20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/swarm/topology.rs b/src/swarm/topology.rs
index 57856b6..b40b120 100644
--- a/src/swarm/topology.rs
+++ b/src/swarm/topology.rs
@@ -107,6 +107,26 @@ pub(crate) struct NeighbourChange {
pub(crate) removed: Vec<String>,
}
+/// Recomputes the neighbours whenever something they depend on may have changed
+/// (`AppState::topology_changed`): the member list (`swarm::sync::run_change_publisher`),
+/// a peer becoming unreachable or reachable again (`swarm::peer`), and every 5 s as a
+/// fallback, which also covers unreachability expiring after `dormant_probe`. A burst of
+/// notifications coalesces into one recomputation.
+pub(crate) async fn run_worker(state: AppState) {
+ loop {
+ state.topology_changed.notified().await;
+ if let Some(change) = refresh(&state).await {
+ crate::swarm::peer::apply_neighbour_change(&state, change).await;
+ }
+ }
+}
+
+/// Whether a change at `path` may change the neighbours: one in the member list, or the
+/// root (the whole document replaced, as after an epoch switch).
+pub(crate) fn affects_neighbours(path: &[String]) -> bool {
+ path.is_empty() || path.starts_with(&members::members_dir())
+}
+
/// Recomputes the neighbours once ready, if the member list, the reachable members or
/// `k` changed.
pub(crate) async fn refresh(state: &AppState) -> Option<NeighbourChange> {