diff options
| -rw-r--r-- | docs/peers.md | 3 | ||||
| -rw-r--r-- | src/document/sync.rs | 12 | ||||
| -rw-r--r-- | src/swarm/sync.rs | 8 |
3 files changed, 16 insertions, 7 deletions
diff --git a/docs/peers.md b/docs/peers.md index d22fef6..4775e85 100644 --- a/docs/peers.md +++ b/docs/peers.md @@ -170,7 +170,8 @@ recent remake, or a return after much was written, gets the bulk of its changes. downloads one delta at a time: while a large one comes, it lacks those changes, so its other neighbours offer them too, and they would come once per offer. Offers that come meanwhile wait; once the delta is in, the node syncs with those that offered, which then -send only what is still missing. +send only what is still missing. What a delta brought counts as known to its sender, as +what its sync messages bring does: none of it goes back, by message or as a delta. Towards a peer on a slow link the limit is lower: a message is offered as a delta if it would take more than 5 s at the throughput measured to that peer (`syncThroughput`, diff --git a/src/document/sync.rs b/src/document/sync.rs index e921b22..2921bb9 100644 --- a/src/document/sync.rs +++ b/src/document/sync.rs @@ -347,11 +347,13 @@ impl SyncSession { } /// The changes since `before` in `doc` came from the peer (we just applied its - /// message): it has them, so they never go back to it. Automerge goes by what it - /// last heard the peer has, and a message that overtook another makes that older - /// than what the peer sent since: the answer would carry the peer's own changes - /// back. Counted as sent (`sent_hashes`), they don't; Automerge forgets them as sent - /// once the peer's heads cover them. (Changes kept until their predecessors came, + /// message, or a delta it offered): it has them, so they never go back to it. + /// Automerge goes by what it last heard the peer has, and a message that overtook + /// another makes that older than what the peer sent since: the answer would carry + /// the peer's own changes back. A delta comes outside the sync protocol, so + /// Automerge would think the peer lacks all of it, and offer it back as a delta of + /// our own. Counted as sent (`sent_hashes`), they don't; Automerge forgets them as + /// sent once the peer's heads cover them. (Changes kept until their predecessors came, /// from another peer, count too: should this one lack them, it asks, and gets them, /// `resend_if_needed`.) pub(crate) fn came_from_peer( diff --git a/src/swarm/sync.rs b/src/swarm/sync.rs index dcb29a7..8059fe2 100644 --- a/src/swarm/sync.rs +++ b/src/swarm/sync.rs @@ -663,8 +663,14 @@ async fn download_and_apply_delta( stats.propagated(delays); } if let Some(peer_state) = peer_state { + let mut peer_state = peer_state.blocking_lock(); // Sync from it made progress: no heal for a while (`keepalive`). - peer_state.blocking_lock().last_sync_rx = Some(Instant::now()); + peer_state.last_sync_rx = Some(Instant::now()); + if changed { + // From its history: none goes back (`SyncSession::came_from_peer`), nor + // is offered back as a delta. + peer_state.sync.came_from_peer(&replica.doc, &heads_before); + } } Ok(changed) }) |
