diff options
| author | tv <tv@krebsco.de> | 2026-11-06 20:22:03 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-11-06 20:22:03 +0100 |
| commit | 36a4a54b1c9204d72e405f5bbfa2a1b595ccba04 (patch) | |
| tree | ebf7c8cf135ebb2684f78a42f2876a0675300624 /src/swarm/flood.rs | |
| parent | 5994b49412c058079639585501a78e6458fdbb6f (diff) | |
flood dissemination
Diffstat (limited to 'src/swarm/flood.rs')
| -rw-r--r-- | src/swarm/flood.rs | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/swarm/flood.rs b/src/swarm/flood.rs new file mode 100644 index 0000000..39cb096 --- /dev/null +++ b/src/swarm/flood.rs @@ -0,0 +1,65 @@ +//! Flooding (`--dissemination flood`, `swarm::dissemination`): a node pushes every +//! change it gets, at once, to every neighbour but the one it came from. The broadcast +//! HyParView's paper pairs its views with, and what PlumTree prunes down to a tree: the +//! baseline the others are measured against. Every link carries every change about +//! twice (once each way, where both ends got it before the other's push came), so the +//! messages grow with the neighbours each member keeps; the latency is that of the +//! fastest path, with no tree to compute or to repair. + +use async_trait::async_trait; + +use crate::document::ChangeHash; +use crate::state::AppState; +use crate::swarm::dissemination::{Dissemination, pass_on}; +use crate::swarm::topology; +use crate::swarm::tree::Plan; + +pub(crate) struct Flood; + +#[async_trait] +impl Dissemination for Flood { + fn name(&self) -> &'static str { + "flood" + } + + /// Every neighbour gets the writer's changes at once, and is told of them in the slow + /// round too (`Plan::alone`): with every neighbour a child, no round would tell + /// anyone, and a push lost on a lossy link waited for the next write, or a keepalive. + async fn plan(&self, state: &AppState, writer: u64) -> Option<Plan> { + let _ = writer; + let neighbours = topology::our_neighbours(state); + Some(Plan { + children: neighbours.clone(), + alone: neighbours, + uncovered: Vec::new(), + covered: Vec::new(), + }) + } + + async fn forward( + &self, + state: &AppState, + writer: u64, + from: &str, + changes: &[ChangeHash], + ) -> Option<Plan> { + let plan = self.plan(state, writer).await?; + Some(pass_on(state, writer, from, changes, plan).await) + } + + /// Counted as the trees' counters count (`/admin/stats`): a push with nothing new as + /// a message from another than the parent. + async fn note_arrival( + &self, + state: &AppState, + peer: &str, + writer: Option<u64>, + carried: bool, + authors: &[(String, Vec<ChangeHash>)], + ) { + let _ = peer; + if writer.is_some() && carried && authors.is_empty() { + state.stats.tree_from_other(); + } + } +} |
