Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add deltaSrc to replication protocol #2242

Merged
merged 4 commits into from
Apr 9, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 35 additions & 23 deletions modules/docs/pages/replication-protocol.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ aware (i.e. each collection can have its own checkpoint). If this message is se
Response:

`rev`: The MVCC revision ID of the checkpoint (_not_ the same as a document revID!) +

Body: JSON data of the checkpoint

[[getCollections]]
Expand All @@ -137,6 +138,7 @@ setCheckpoint
`client`: Unique ID of client checkpoint to store +
`rev`: Last known MVCC revision ID of the checkpoint _(omitted if this
is a new checkpoint)_ +

Body: JSON data of checkpoint

Stores a checkpoint on the receiver. The JSON object in the request body
Expand Down Expand Up @@ -167,8 +169,9 @@ _(optional)_ +
`versioning`: `rev-trees` (default) or `version-vectors` -- see the <<revIDs>> section. +
_other properties_: Named parameters for the filter function
_(optional)_ +
Body: JSON dictionary _(optional)_ +
`sendReplacementRevs`: Boolean indicating whether the passive peer (pusher) should send replacement revs rather than NoRev when the body of a requested rev is unavailable and a newer revision is available. _(optional)_
`sendReplacementRevs`: Boolean indicating whether the passive peer (pusher) should send replacement revs rather than NoRev when the body of a requested rev is unavailable and a newer revision is available. _(optional)_ +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Random space added?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not random, it is required to put this text on a newline. https://docs.asciidoctor.org/asciidoc/latest/blocks/hard-line-breaks/

Without this, the next line would be on the same line.


Body: JSON dictionary _(optional)_

Asks the recipient to begin sending change messages starting from the
sequence just after the one given by the `since` property, or from the
Expand Down Expand Up @@ -255,6 +258,7 @@ would resolve it and push the merge.
Response:

`maxHistory`: Max length of revision history to send _(optional; not used with version vectors)_ +

Body: JSON array (see below)

The response message indicates which revisions the recipient wants to
Expand Down Expand Up @@ -335,13 +339,15 @@ replacementRev, this is the originally requested Revision ID. _(optional)_ +
`sequence`: Sequence ID, JSON-encoded _(optional unless unsolicited,
q.v.)_. If this is a replacementRev, this will be the sequence of the original requested rev. +
`history`: Revision history (list of revision IDs) -- see the <<revIDs>> section. +
`noconflicts`: true if the revision may not create a conflict _(optional; default is false)_ +
`deltaSrc`: The revision that the body is a delta from. If not included, the body is a full revision. _(optional)_ +

Body: Document JSON
`noconflicts`: true if the revision may not create a conflict _(optional; default is false)_

Sends one document revision, either meant for the specified collection or the default collection if one is not specified. The `id`, `rev`, `deleted` properties are
optional if corresponding `_id`, `_rev`, `_deleted` properties exist in
the JSON body (and vice versa.) The `sequence` property is optional
unless this message was unsolicited.
unless this message was unsolicited. If the `deltaSrc` is specified, the body is a delta from the revision specified in the `deltaSrc` property.

If the `noconflicts` flag is set, or if the recipient is in conflict-free mode,
it MUST check whether the `history` array contains the current local revision ID,
Expand All @@ -368,9 +374,11 @@ The recipient MUST send a response unless the request was sent
added the revision to its database, or has failed to add it. On success
the response can be empty; on failure it MUST be an error.

Note: The recipient may need to send one or more `getattach` messages
The sender may send this as `noreply` if there are no attachments or `deltaSrc` is not present.

Note: The recipient may need to send one or more `getAttachment` messages
while processing the `rev` message, in which case it MUST NOT send the
`rev`'s response until it's received responses to the `getattach`
``rev``'s response until it's received responses to the `getAttachment`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the need for double backtick?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise, this whole section is indented.

message(s) and durably added the attachments, as well as the document,
to its database.

Expand All @@ -384,14 +392,15 @@ norev
`sequence`: Sequence ID, JSON-encoded _(optional)_ +
`error`: The error number, which should correspond to HTTP Response status codes +
`reason`: A more detailed description of the cause of the error _(optional)_

Body: None

In the case a rev is requested from a peer via a `changes` or `subChanges` response,
but that revision is not available, and the peer's message did not include the `sendReplacementRevs` property (set to true), the `norev` message should be sent
as a placeholder to inform the `peer` that there will be no corresponding
`rev` message sent for the requested revision. This prevents the peer
from waiting for a `rev` message that will never come, which could cause
the replication to get stuck.
the replication to get stuck. This message is always sent with `noreply`.


[[getattachment]]
Expand Down Expand Up @@ -433,6 +442,7 @@ proveAttachment
`collection` [3.1+]: Indicates the index of the collection to operate on for this message, indexed by the list resolved in `getCollections`. If legacy `getCheckpoint` is used, this property *must* be omitted +
`digest`: Attachment digest (as found in document `_attachments`
metadata.) +

Body: A _nonce_: 16 to 255 bytes of random binary data

Asks the recipient to prove that it has the body of the attachment with
Expand Down Expand Up @@ -532,14 +542,15 @@ it wants and which ancestors it already has
with a BLIP/409 or HTTP/409 error, and instead accept `proposeChanges`
messages.
5. For each requested revision:
1. Client sends document body in a `rev` message
2. Server looks at each newly-added attachment digest in each revision
[arabic,start=1]
.. Client sends document body in a `rev` message
.. Server looks at each newly-added attachment digest in each revision
and
* sends a `getAttachment` for each attachment it doesn't have; client
** sends a `getAttachment` for each attachment it doesn't have; client
sends data
* sends a `proveAttachment` for each attachment it already has; client
** sends a `proveAttachment` for each attachment it already has; client
sends proof
3. Server adds revision & attachments to database, and sends success
.. Server adds revision & attachments to database, and sends success
response to the client's `rev` message.
6. Client periodically sends `setCheckpoint` as progress updates
7. When all revisions and attachments have been sent, client either
Expand Down Expand Up @@ -579,17 +590,17 @@ Push interaction diagram
│ │
├──────────────────────────────rev RQ [{docId, rev1, body}]──────────────────────────────▶
│ │
getAttach RQ
getAttachment RQ
◀───────────────────────────────────────[digest]─────────────────────────────────────────┤
│ │
│ │
├──────────────────────────────────getAttach RSP [body]──────────────────────────────────▶
├──────────────────────────────────getAttachment RSP [body]──────────────────────────────
│ │
│ │
◀──────────────────────────────────getAttach RQ [digest]─────────────────────────────────┤
◀──────────────────────────────────getAttachment RQ [digest]─────────────────────────────
│ │
│ │
├───────────────────────────────────getAttach RSP [body]─────────────────────────────────▶
├───────────────────────────────────getAttachment RSP [body]─────────────────────────────
│ │
│ │
◀───────────────────────────────────────rev RSP []───────────────────────────────────────┤
Expand Down Expand Up @@ -626,11 +637,12 @@ next message until a response is received.
5. Client replies to each `changes` message indicating which revisions
it wants and which ancestors it already has
6. For each requested revision:
1. Server sends document body in a `rev` message
2. Client looks at each newly-added attachment digest in each revision
[arabic,start=1]
.. Server sends document body in a `rev` message
.. Client looks at each newly-added attachment digest in each revision
and sends a `getAttachment` for each attachment it doesn't have; server
sends data
3. Client adds revision & attachments to database, and sends success
.. Client adds revision & attachments to database, and sends success
response to the server's `rev` message.
7. Client periodically sends `setCheckpoint` as progress updates
8. When there are no more changes, server sends a `changes` message
Expand Down Expand Up @@ -680,17 +692,17 @@ Pull interaction digram
│ │
◀──────────────────────────────rev RQ [{docId, rev1, body}]──────────────────────────────┤
│ │
getAttach RQ
getAttachment RQ │
├───────────────────────────────────────[digest]─────────────────────────────────────────▶
│ │
│ │
◀──────────────────────────────────getAttach RSP [body]──────────────────────────────────┤
◀──────────────────────────────────getAttachment RSP [body]──────────────────────────────┤
│ │
│ │
├──────────────────────────────────getAttach RQ [digest]─────────────────────────────────▶
├──────────────────────────────────getAttachment RQ [digest]─────────────────────────────▶
│ │
│ │
◀───────────────────────────────────getAttach RSP [body]─────────────────────────────────┤
◀───────────────────────────────────getAttachment RSP [body]─────────────────────────────┤
│ │
│ │
├───────────────────────────────────────rev RSP []───────────────────────────────────────▶
Expand Down
Loading