summaryrefslogtreecommitdiffstats
path: root/src/swarm/peer.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-10-22 21:55:36 +0200
committertv <tv@krebsco.de>2026-10-22 21:55:36 +0200
commita098d7e5eaf486fe3d9813f690745619121bac65 (patch)
tree8fbff9c158c2bbadcb70ad30fc4b485f16bd10bb /src/swarm/peer.rs
parentc97161adb3142041c00d649a51924318b5a2d6e4 (diff)
don't resend sync messages to up-to-date peers
When an sync messages arrives and automerge has nothing to say about it, then no reply is generated. With c9279e4 it was assumed that every sync message gets an answer, so missing replies caused unnecessary resends. Now a reply is only awaited if the peer's last reported heads differ from ours. If the peer's heads become equal through a third peer without replying, the waiting will also abort if a ping or pong showss the same heads digest on both sides.
Diffstat (limited to 'src/swarm/peer.rs')
-rw-r--r--src/swarm/peer.rs21
1 files changed, 15 insertions, 6 deletions
diff --git a/src/swarm/peer.rs b/src/swarm/peer.rs
index 42ea276..d88e63c 100644
--- a/src/swarm/peer.rs
+++ b/src/swarm/peer.rs
@@ -133,12 +133,21 @@ async fn heal_if_diverged(
return;
};
- let heal = peer_state_mutex.lock().await.needs_heal(
- &local.heads_digest,
- &remote.heads_digest,
- &state.timing,
- Instant::now(),
- );
+ let heal = {
+ let mut peer_state = peer_state_mutex.lock().await;
+ if local.heads_digest == remote.heads_digest {
+ // Same document: whatever answer we were waiting for, there is nothing left
+ // to send. (Automerge answers only when it has something to say, so a sync
+ // message to a peer that already has everything gets no reply at all.)
+ peer_state.sync_in_step();
+ }
+ peer_state.needs_heal(
+ &local.heads_digest,
+ &remote.heads_digest,
+ &state.timing,
+ Instant::now(),
+ )
+ };
if heal {
warn!(peer = %peer, "Documents differ and sync is idle; re-handshaking to restart sync");