From 065bf2f9e738eae219da1fe0557ec22f94f10b7a Mon Sep 17 00:00:00 2001 From: tv Date: Thu, 5 Nov 2026 16:10:14 +0100 Subject: waiting not twice --- src/swarm/stats.rs | 9 +++++++++ src/swarm/sync.rs | 9 ++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'src/swarm') diff --git a/src/swarm/stats.rs b/src/swarm/stats.rs index 31b6a3b..ba75d68 100644 --- a/src/swarm/stats.rs +++ b/src/swarm/stats.rs @@ -157,6 +157,10 @@ pub(crate) struct Relay { pub(crate) carrying_bloom_bytes: u64, pub(crate) nothing_new_change_bytes: u64, pub(crate) nothing_new_bloom_bytes: u64, + /// Sync messages received that carried changes, none of them applied yet: they wait + /// for predecessors that didn't come (Automerge holds them back). Not counted with + /// `nothing_new`, which they aren't. + pub(crate) waiting: u64, /// The changes new to us that sync messages brought (beside what they carried that /// we had): with `carrying` less `nothing_new`, how many a message with news brings. pub(crate) new_changes: u64, @@ -314,6 +318,11 @@ impl NodeStats { inner.relay.nothing_new_bloom_bytes += sizes.1 as u64; } + /// A sync message carried changes that wait for predecessors (`Relay::waiting`). + pub(crate) fn waiting(&self) { + self.lock().relay.waiting += 1; + } + /// Changes from elsewhere were applied, `delays_ms` after they were committed, that /// came not along a writer's tree. pub(crate) fn off_tree(&self, delays_ms: &[i64]) { diff --git a/src/swarm/sync.rs b/src/swarm/sync.rs index 0edc277..5511ea2 100644 --- a/src/swarm/sync.rs +++ b/src/swarm/sync.rs @@ -574,6 +574,7 @@ pub(crate) async fn handle_sync( peer_state.last_heads = Some((epoch, transport::HeadsSummary::of(message.heads().to_vec()))); let heads_before = replica.heads().to_vec(); + let said = message.heads().to_vec(); let sync = &mut peer_state.sync; replica @@ -617,7 +618,13 @@ pub(crate) async fn handle_sync( stats.new_changes(new); } if carried && !changed { - stats.nothing_new(payload_len, writer.is_some(), delivered, sizes); + // Its heads not ours yet: what it brought waits for predecessors, which + // isn't having come twice. + if !crate::document::changes::holds_all(&replica.doc, &said) { + stats.waiting(); + } else { + stats.nothing_new(payload_len, writer.is_some(), delivered, sizes); + } } // Whose they are, to pass them on along their writers' trees, however they // came (along a tree, with an answer, pulled). -- cgit v1.3.1