aboutsummaryrefslogtreecommitdiffstats
path: root/src/swarm/topology/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/swarm/topology/mod.rs')
-rw-r--r--src/swarm/topology/mod.rs22
1 files changed, 19 insertions, 3 deletions
diff --git a/src/swarm/topology/mod.rs b/src/swarm/topology/mod.rs
index ea71712..e494f34 100644
--- a/src/swarm/topology/mod.rs
+++ b/src/swarm/topology/mod.rs
@@ -30,7 +30,7 @@ use std::collections::{BTreeMap, BTreeSet};
use tracing::info;
use crate::locks::RwLockExt;
-use crate::state::AppState;
+use crate::state::{AppState, PeerState};
use crate::swarm::members;
mod graph;
@@ -164,10 +164,26 @@ pub(crate) struct NeighbourChange {
pub(crate) removed: Vec<String>,
}
+/// Runs `change` on a peer's state, and has the neighbours recomputed (`run_worker`) if
+/// it changed what they are chosen from (`PeerState::neighbour_inputs`). Changes to a
+/// peer that may matter to the neighbours go through here.
+pub(crate) fn change_peer<T>(
+ state: &AppState,
+ peer_state: &mut PeerState,
+ change: impl FnOnce(&mut PeerState) -> T,
+) -> T {
+ let before = peer_state.neighbour_inputs();
+ let result = change(peer_state);
+ if peer_state.neighbour_inputs() != before {
+ state.topology_changed.notify_one();
+ }
+ result
+}
+
/// Recomputes the neighbours whenever something they depend on may have changed
/// (`AppState::topology_changed`): the member list (`swarm::changes::run_change_publisher`),
-/// a peer becoming unreachable or reachable again (`swarm::peer`), and every 5 s as a
-/// fallback. A burst of notifications coalesces into one recomputation.
+/// a peer's state (`change_peer`), and every 5 s as a fallback (`swarm::peer`). A burst
+/// of notifications coalesces into one recomputation.
pub(crate) async fn run_worker(state: AppState) {
loop {
state.topology_changed.notified().await;