1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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();
}
}
}
|