//! 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 { 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 { 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, carried: bool, authors: &[(String, Vec)], ) { let _ = peer; if writer.is_some() && carried && authors.is_empty() { state.stats.tree_from_other(); } } }