diff options
Diffstat (limited to 'src/swarm/sync.rs')
| -rw-r--r-- | src/swarm/sync.rs | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/src/swarm/sync.rs b/src/swarm/sync.rs index 3284015..80d6d56 100644 --- a/src/swarm/sync.rs +++ b/src/swarm/sync.rs @@ -32,6 +32,12 @@ pub(crate) struct ChangeSet { } async fn deliver_sync_to_peer(state: &AppState, peer: &str) -> Result<()> { + if state.remake.fetching_snapshot() { + // Rejoining: the snapshot comes as a download, not in a sync message. Sync + // starts once it is here (`remake::catchup`). + trace!("Waiting for the snapshot download; not syncing yet"); + return Ok(()); + } let Some(peer_state_mutex) = state.get_peer_state(peer).await else { trace!("Peer was forgotten; skipping synchronization"); return Ok(()); @@ -337,7 +343,7 @@ pub(crate) async fn handle_sync( let mut peer_state = peer_state_mutex.blocking_lock(); peer_state.reports_ready = Some(from_ready); - let heads_before = replica.doc.get_heads(); + let heads_before = replica.heads().to_vec(); replica .doc @@ -354,7 +360,8 @@ pub(crate) async fn handle_sync( peer_state.sync.reply_settled(); resend_if_needed(&peer, &mut peer_state.sync.state); - let heads_after = replica.doc.get_heads(); + replica.refresh_heads(); + let heads_after = replica.heads().to_vec(); stats.heads_seen(heads_after.len()); let changed = heads_after != heads_before; if changed && measure_propagation { @@ -372,8 +379,11 @@ pub(crate) async fn handle_sync( } Ok(Some(( - // Only from a ready peer: a peer still catching up has empty heads, which - // every document "contains". + // Only from a ready peer, and only if it has heads at all: empty heads are + // "contained" in every document, so they prove nothing. A peer still + // catching up has them, and so does a ready peer whose document is empty + // (a misconfigured second swarm, or a genesis node in its first seconds, + // before it registered itself). check_caught_up && from_ready && peer_state @@ -382,9 +392,10 @@ pub(crate) async fn handle_sync( .their_heads .as_ref() .is_some_and(|heads| { - heads - .iter() - .all(|h| replica.doc.get_change_by_hash(h).is_some()) + !heads.is_empty() + && heads + .iter() + .all(|h| replica.doc.get_change_by_hash(h).is_some()) }), changed, ))) |
