summaryrefslogtreecommitdiffstats
path: root/src/swarm
diff options
context:
space:
mode:
Diffstat (limited to 'src/swarm')
-rw-r--r--src/swarm/peer.rs21
-rw-r--r--src/swarm/sync.rs16
2 files changed, 28 insertions, 9 deletions
diff --git a/src/swarm/peer.rs b/src/swarm/peer.rs
index d801b0f..bad8e24 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");
diff --git a/src/swarm/sync.rs b/src/swarm/sync.rs
index 0c7148e..e294201 100644
--- a/src/swarm/sync.rs
+++ b/src/swarm/sync.rs
@@ -110,9 +110,19 @@ async fn deliver_sync_to_peer(state: &AppState, peer: &str, retry_delivery: bool
peer_state.needs_generate = false;
let epoch = replica.epoch;
let sent_before = peer_state.sync_state.sent_hashes.clone();
- let sync_doc = replica.doc.sync();
- let message = sync_doc.generate_sync_message(&mut peer_state.sync_state);
- if message.is_some() {
+ let message = {
+ let sync_doc = replica.doc.sync();
+ sync_doc.generate_sync_message(&mut peer_state.sync_state)
+ };
+ // A peer whose heads are ours already has everything; Automerge
+ // answers only when it has something to say, so it will stay
+ // silent. Waiting for an answer would only end in a pointless
+ // resend.
+ let in_step = peer_state.sync_state.their_heads.as_ref()
+ == Some(&replica.doc.get_heads());
+ if in_step {
+ peer_state.sync_in_step();
+ } else if message.is_some() {
let sent = peer_state
.sync_state
.sent_hashes