aboutsummaryrefslogtreecommitdiffstats
path: root/src/swarm
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-06 20:22:03 +0100
committertv <tv@krebsco.de>2026-11-06 20:22:03 +0100
commit36a4a54b1c9204d72e405f5bbfa2a1b595ccba04 (patch)
treeebf7c8cf135ebb2684f78a42f2876a0675300624 /src/swarm
parent5994b49412c058079639585501a78e6458fdbb6f (diff)
flood dissemination
Diffstat (limited to 'src/swarm')
-rw-r--r--src/swarm/dissemination.rs3
-rw-r--r--src/swarm/flood.rs65
-rw-r--r--src/swarm/mod.rs1
3 files changed, 69 insertions, 0 deletions
diff --git a/src/swarm/dissemination.rs b/src/swarm/dissemination.rs
index 93ad4e9..9763449 100644
--- a/src/swarm/dissemination.rs
+++ b/src/swarm/dissemination.rs
@@ -139,6 +139,8 @@ pub(crate) enum Kind {
WritersTrees,
/// PlumTree (`swarm::plumtree`).
Plumtree,
+ /// Flooding (`swarm::flood`).
+ Flood,
}
impl Kind {
@@ -146,6 +148,7 @@ impl Kind {
match self {
Kind::WritersTrees => std::sync::Arc::new(crate::swarm::tree::WritersTrees),
Kind::Plumtree => std::sync::Arc::new(crate::swarm::plumtree::PlumTree::default()),
+ Kind::Flood => std::sync::Arc::new(crate::swarm::flood::Flood),
}
}
}
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();
+ }
+ }
+}
diff --git a/src/swarm/mod.rs b/src/swarm/mod.rs
index 63ddcfa..ccffaa0 100644
--- a/src/swarm/mod.rs
+++ b/src/swarm/mod.rs
@@ -7,6 +7,7 @@ pub(crate) mod bootstrap;
pub(crate) mod changes;
pub(crate) mod dissemination;
pub(crate) mod document_file;
+pub(crate) mod flood;
pub(crate) mod hop;
pub(crate) mod hyparview;
pub(crate) mod links;