Skip to content

Commit fe91fa3

Browse files
committed
docs(connectivity): document peer id collisions and replica identity
Explains why replicas must use unique peer ids, how Origin detects and rejects collisions, how to recover, and how to interpret ops_trimmed in sync session logs.
1 parent d01e3dc commit fe91fa3

1 file changed

Lines changed: 31 additions & 1 deletion

File tree

docs/connectivity/sync-protocol.rdx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,36 @@ Schema changes (new columns, new collections) are discovered automatically by co
2828
5. Origin validates constraints (UNIQUE, FK, CHECK) via Raft
2929
6. Committed deltas are broadcast to all connected clients with matching shape subscriptions
3030

31+
## Replica Identity
32+
33+
Every CRDT operation is attributed to the **peer id** of the replica that made it. A peer id must belong to exactly one replica of one collection.
34+
35+
Two replicas that share a peer id number their operations from the same counter range. The merge cannot tell those apart from a client re-sending history it has already delivered, so it discards whichever arrives second — the writes are gone, and to the client they looked accepted.
36+
37+
Origin therefore binds each peer id to the first producer that uses it in a collection, and refuses any other producer:
38+
39+
```
40+
DeltaReject: PEER_ID_COLLISION: peer id 1 on collection 'notes' is already
41+
owned by another replica; generate a new peer id and resync
42+
```
43+
44+
To recover, generate a fresh peer id for the replica and resync. Applications should:
45+
46+
- Derive a peer id that is unique per **installation**, not per user or per device model.
47+
- Generate a **new** peer id whenever the local store is reset, reinstalled, or restored from a backup taken by another replica. A replica that keeps its old peer id after wiping its store collides with its own earlier history, which Origin cannot refuse — it owns that peer id — and the writes are reported as duplicates rather than applied.
48+
49+
The same peer id in two different collections is not a collision; each collection is a separate document whose counter ranges never meet.
50+
51+
### Observing discarded operations
52+
53+
Each sync session's close line reports what the merge absorbed:
54+
55+
```
56+
sync: session closed session=... applied=40 rejected=0 deduplicated=10 ops_trimmed=120
57+
```
58+
59+
`ops_trimmed` counts operations that arrived already known to Origin. A healthy resync re-sends a prefix and then advances, so `applied` rises alongside it. A session whose deltas are all deduplicated with nothing applied is the peer-id collision shape.
60+
3161
## Shape Subscriptions
3262

3363
Devices subscribe to a subset of data via shape subscriptions (wire-level sync feature, not SQL):
@@ -48,6 +78,6 @@ If a local write violates a constraint on Origin, a typed `CompensationHint` is
4878
- `IntegrityViolation` — other integrity-rule violation
4979
- `PermissionDenied` — insufficient privilege
5080
- `RateLimited` — quota or rate limit exceeded
51-
- `Custom` — application-specific handling
81+
- `Custom` — application-specific handling, including `peer_id_collision` (see [Replica Identity](#replica-identity))
5282

5383
The application handles the conflict — no silent data loss.

0 commit comments

Comments
 (0)