diff options
Diffstat (limited to 'src/swarm/tree.rs')
| -rw-r--r-- | src/swarm/tree.rs | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/src/swarm/tree.rs b/src/swarm/tree.rs index b9491b3..064f5b9 100644 --- a/src/swarm/tree.rs +++ b/src/swarm/tree.rs @@ -363,13 +363,55 @@ pub(crate) struct Latencies { /// neighbours said); None if we have none, or no tree is known. #[cfg(test)] pub(crate) async fn own_parent(state: &AppState, writer: &str) -> Option<String> { - let (graph, distance) = distances(state, topology::pair_key(writer))?; + our_parent(state, topology::pair_key(writer)).await +} + +/// `own_parent`, of the writer by pair key. +async fn our_parent(state: &AppState, writer: u64) -> Option<String> { + let (graph, distance) = distances(state, writer)?; let known = known_reaches(state, &graph).await; let reached = |by: &str, member: &str| known.reached(by, member); let round_trip = |by: &str, member: &str| known.round_trip(by, member); parent(&graph, &distance, &reached, &round_trip, state.local_id()).map(str::to_owned) } +/// Whether the trees work, from what arrives (`swarm::stats`, `/admin/stats`): a sync +/// message from `peer` along `writer`'s tree that `carried` changes, where we have a +/// parent in it and it isn't `peer` (a double send, or views of the tree that differ); +/// the changes of `authors` (by author) that came with a message along no tree, where +/// we have a parent in their writer's tree (the tree didn't bring them, or not first). +/// Not while catching up, when everything comes another way. +pub(crate) async fn note_arrival( + state: &AppState, + peer: &str, + writer: Option<u64>, + carried: bool, + authors: &[(String, Vec<crate::document::ChangeHash>)], +) { + match writer { + Some(writer) if carried => { + if our_parent(state, writer) + .await + .is_some_and(|parent| parent != peer) + { + state.stats.tree_from_other(); + } + } + None => { + for (author, changes) in authors { + if author != state.local_id() + && our_parent(state, topology::pair_key(author)) + .await + .is_some() + { + state.stats.tree_missed(changes.len()); + } + } + } + Some(_) => {} + } +} + /// Where we are in `writer`'s tree, as we see it: our distance from the writer, our /// parent (`parent`), and the neighbours we reach that come before us (whom we could /// take). None while the member list isn't known, or the writer or we aren't in it. |
