no power loss
This commit is contained in:
parent
d56084e4bc
commit
2fcdbfd27d
1 changed files with 1374 additions and 3676 deletions
|
|
@ -1,8 +1,7 @@
|
|||
# Sync algorithm
|
||||
|
||||
The current API v5 server stores immutable content versions and a separately
|
||||
versioned file manifest. Clients reconcile snapshots and apply them through a
|
||||
durable filesystem journal. The server does not merge competing edits.
|
||||
versioned file manifest. Clients reconcile snapshots with the current local files. The server does not merge competing edits.
|
||||
|
||||
## Identity and ordering
|
||||
|
||||
|
|
@ -19,10 +18,11 @@ UUID is rejected.
|
|||
|
||||
## Reconciliation
|
||||
|
||||
A new client reads a coherent vault snapshot, applies it durably, then replays
|
||||
subsequent events. Replayed pages are folded to their final document heads and
|
||||
manifest before changing local files. This avoids applying intermediate remote
|
||||
edits that were already reverted.
|
||||
A new client reads a coherent vault snapshot, applies it, then replays
|
||||
subsequent events over HTTP. Pages are folded in memory to their final document
|
||||
heads and manifest before changing local files. Interrupted fetching restarts from
|
||||
the last incorporated cursor without saved pagination state. This avoids applying
|
||||
intermediate remote edits that were already reverted.
|
||||
|
||||
For text, the client compares the common base, current local bytes and current
|
||||
remote bytes using `reconcile-text`. Configured extensions and valid UTF-8 without
|
||||
|
|
@ -31,34 +31,36 @@ they do not authorize the server to merge a stale base. Large diff operation set
|
|||
are sent as snapshots.
|
||||
|
||||
If only one side changed, that side is retained. Concurrent unmergeable changes
|
||||
keep the server version while the journal archives displaced local bytes for
|
||||
recovery. First contact with existing local text has no shared ancestor and uses
|
||||
keep the server version. First contact with existing local text has no shared ancestor and uses
|
||||
an empty parent. Concurrent edits may still require human review.
|
||||
|
||||
Paths use a separate three-way decision: keep a local change when the server path
|
||||
is unchanged, otherwise prefer the server path if both changed. Portable-name
|
||||
collisions receive deterministic conflict names. A manifest deletion is not
|
||||
reversed merely because another client edited the document; displaced bytes are
|
||||
retained locally.
|
||||
reversed merely because another client edited the document. Local backup archives
|
||||
are not created.
|
||||
|
||||
## Filesystem application
|
||||
|
||||
Before moving files, the client persists a journal describing sources,
|
||||
destinations and replacement snapshots. It stages sources before installing any
|
||||
destination, so swaps and rename cycles do not overwrite each other. Prepared
|
||||
content is persisted before installation so a crash does not repeat a merge.
|
||||
The client applies an in-memory plan directly to the visible namespace, then
|
||||
saves one metadata snapshot. Swaps and cycles move occupied sources to temporary
|
||||
conflict names that remain ordinary discoverable files if application stops.
|
||||
There is no persisted filesystem plan, staged payload, recovery replay or fsync
|
||||
protocol. An interruption may leave a subset of the operations visible, or partial
|
||||
file content; the next scan reconciles whatever is present then.
|
||||
|
||||
External notifications retain logical document identities. Notifications received
|
||||
during asynchronous filesystem reads or staging are incorporated before accepting
|
||||
a source. An editor save to a staged document's old path remains part of that
|
||||
document. Ignored and oversized physical occupants are protected during conflict
|
||||
allocation. Adapters report atomic editor saves as content updates and suppress
|
||||
notifications generated by the engine itself.
|
||||
Create, delete and move notifications persist logical document identities; content
|
||||
updates only wake the loop to reread current bytes. Namespace changes detected
|
||||
before mutations invalidate the plan. Notifications during application are incorporated
|
||||
between files using their document identities; the next scan rereads content. Content is reread
|
||||
before replacement. Ignored and oversized occupants stay in place. Adapters
|
||||
report atomic editor saves as updates and suppress engine-generated notifications.
|
||||
|
||||
The filesystem and metadata store have separate durability boundaries. Recovery
|
||||
replays the journal before scanning, including when network sync is disabled.
|
||||
Adapters must provide complete scans, coherent snapshots, exclusive vault access,
|
||||
no-replace renames and durable writes. Recovery artifacts are excluded from sync.
|
||||
Metadata persistence must replace a complete value atomically, leaving a readable
|
||||
old/new value after interruption. Metadata and user files need not describe the
|
||||
same moment: scans repair that disagreement. File creation and rename must reject
|
||||
occupied destinations; scans must be complete and reads coherent. No guarantee is
|
||||
made that user bytes or rename identities survive power loss.
|
||||
|
||||
## Server restores and failures
|
||||
|
||||
|
|
@ -68,8 +70,7 @@ The client persists and echoes it; the server rejects a checkpoint from a discar
|
|||
history before executing its request. Each new event gets a fresh token even if
|
||||
its numeric ID or request UUID was used on the discarded branch.
|
||||
|
||||
After a mismatch, the client durably records recovery intent, retains pending
|
||||
content, clears old history-dependent state and bootstraps against the restored
|
||||
After a mismatch, the client records reset intent, clears old history-dependent state and bootstraps against the restored
|
||||
server. Clean files reconcile against the restored snapshot. Unsent edits with an
|
||||
old base are preserved as separate local documents, with conflict names if needed.
|
||||
Interrupted recovery saves are replayable. Backups must be restored with the server
|
||||
|
|
|
|||
Loading…
Reference in a new issue