Skip to content

fix: enforce shallow snapshot concurrency boundaries - #1090

Open
zxch3n wants to merge 4 commits into
feat/wasm-json-text-exportfrom
test/shallow-snapshot-concurrency
Open

fix: enforce shallow snapshot concurrency boundaries#1090
zxch3n wants to merge 4 commits into
feat/wasm-json-text-exportfrom
test/shallow-snapshot-concurrency

Conversation

@zxch3n

@zxch3n zxch3n commented Sep 3, 2026

Copy link
Copy Markdown
Member

Problem and behavior

A shallow replica must reject updates rooted before its retained history without corrupting the document or leaving those updates pending. An update exactly concurrent with the root frontier previously escaped the boundary check: its deps equal the root's own deps, so a version-vector shortcut classified it as acceptable even though the dependency ids were already trimmed. Import then panicked while resolving its Lamport timestamp.

Reject that boundary explicitly with ImportUpdatesThatDependsOnOutdatedVersion. The rejected update never enters pending storage, and later valid post-root imports still work. The fix and the concurrency contract now land together, independently of #1091's export optimization.

Stacked on #1087; #1091 follows this PR.

Contracts and tests

Seven public tests in crates/loro/tests/shallow_snapshot_concurrency.rs cover:

  • Faithful bootstrap and repeated already-included history as a no-op.
  • Causally post-root updates merging normally.
  • Pre-root forks, including the exact root-dependency boundary, being rejected.
  • Post-root missing dependencies pending until delivery.
  • Shallow edits merging back into full-history peers without trimming their history.
  • A pre-root concurrent chain whose genesis is rejected and whose later changes cannot resolve.

DAG and internal import tests additionally assert the exact boundary and that rejected changes are dropped rather than queued. The public boundary regression also verifies subsequent valid imports after rejection. All fixtures use fixed peers and explicit changes, without timing dependencies.

docs/shallow-snapshot-concurrency.md documents these guarantees and their limits: shallow snapshots cannot preserve arbitrary offline forks that diverged before the root. A non-empty target consumes retained changes rather than adopting the snapshot's state sections.

Validation

  • Public concurrency suite: 7 passed.
  • Exact-dependency and dropped-not-pending internal regressions pass.
  • Original boundary reproducer aborted on a0e34943; the corrected path returns the expected error and preserves the document.
  • Changeset included; git diff --check passed.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

WASM Size Report

  • Original size: 3135.07 KB
  • Gzipped size: 1038.82 KB
  • Brotli size: 728.96 KB

@zxch3n
zxch3n force-pushed the test/shallow-snapshot-concurrency branch from 2240dd2 to a0e3494 Compare September 5, 2026 05:15
Backport the dependency-boundary fix from PR #1091 so the guarantees and tests in PR #1090 hold independently. Verify that valid post-root imports still succeed after rejection.

Model: gpt-6
@zxch3n zxch3n changed the title test: pin down shallow snapshot merge semantics with concurrent peers fix: enforce shallow snapshot concurrency boundaries Sep 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant