Make SharedString snapshot format selection sticky - #28370
Tony Murphy (anthony-murphy) wants to merge 6 commits into
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Hi! Thank you for opening this PR. Want me to review it? Based on the diff (788 lines, 11 files), I've queued these reviewers:
How this works
|
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Explicit overrides can be ignored for unchanged DDSs because the channel is not marked dirty.
Review effort: Balanced
Findings: 1
Open (1)
What changed in this PR
Makes SharedString snapshot-format selection persistent while honoring explicit configuration overrides.
Changes:
- Persists the effective snapshot format in per-instance DDS attributes.
- Adds both-format unit, conflict-farm, and end-to-end coverage.
- Documents the option and adds a minor changeset.
| File | Description |
|---|---|
.changeset/sticky-shared-string-snapshot-format.md |
Documents the behavior change. |
packages/dds/merge-tree/src/mergeTree.ts |
Clarifies snapshot-option precedence. |
packages/dds/merge-tree/src/test/client.conflictFarm.spec.ts |
Runs conflict tests with both formats. |
packages/dds/merge-tree/src/test/testClient.ts |
Emits the selected test snapshot format. |
packages/dds/sequence/src/intervalCollectionMapInterfaces.ts |
Adds the snapshot option to sequence options. |
packages/dds/sequence/src/sequence.ts |
Implements sticky, per-instance format selection. |
packages/dds/sequence/src/test/snapshotFormat.spec.ts |
Tests precedence, persistence, and isolation. |
packages/test/test-end-to-end-tests/src/test/sharedStringSnapshotFormat.spec.ts |
Tests summary/reload behavior locally. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Bundle size comparisonBase commit: Notable changesNo bundles changed by ≥ 500 bytes parsed. Per-bundle deltas
|

How contribute to this repo.
Guidelines for Pull Requests.
Description
Make SharedString's flat MergeTree snapshot format opt-in and sticky across summaries and loads. Select the next DDS summary format using explicit configuration/runtime flag, recorded flag, then legacy default. Flat summaries persist
newMergeTreeSnapshotFormat: truein the DDS.attributes; legacy summaries useundefined, so the serialized field is omitted. An explicitfalseoverrides recordedtrueand clears the remembered flat setting when the DDS next summarizes naturally.Use the same effective setting for writer selection and internal bookkeeping, with per-instance attributes to prevent settings leaking between DDSs. Do not dirty an unchanged DDS or force a summary when the setting changes. Leave both snapshot formats, their readers, SharedMatrix, and
snapshotFormatVersionunchanged.Add option documentation, a changeset, attached/detached unit coverage, four SharedString fuzz workloads for inherited settings and explicit overrides, and focused local-server summary/reload tests. DDS fuzz summaries capture the real
.attributesblob after summarization and load those snapshot-time attributes through joining, detached rehydration, and stashing. Fuzz assertions observe summaries already generated by the harness rather than introducing extra summaries that advance live client state. The conflict-farm additions have been removed because they bypass SharedString's DDS attributes and format-selection logic.Omitting the default legacy flag preserves the existing serialized attributes shape. The snapshot-normalizer workaround and its tests have been removed; golden fixtures remain unchanged.
Breaking Changes
None. Both formats remain supported, public API signatures are unchanged, and SharedString defaults to legacy when neither an explicit nor recorded setting exists. Previously recorded
falsevalues are still accepted when loading.Reviewer Guidance
The review process is outlined in the pull request guidelines.
Please focus on explicit-
falseprecedence, clearing versus preserving the serialized flag, per-instance attribute isolation, snapshot-time metadata preservation through fuzz client loads, and agreement between the emitted format and recorded setting. Format changes take effect only when the DDS is naturally summarized, including normal summary-handle reuse for unchanged channels.Validation
The latest simplification was published before running checks, following the author's requested review workflow. The following checks passed on the current revision. Test commands used
FLUID_TEST_MODULE_SYSTEM=ESM; fuzz commands also usedFUZZ_STRESS_RUN=short.pnpm exec fluid-build --root . --task build:test:esm '^@fluidframework/sequence$' '^@fluidframework/merge-tree$' '^@fluidframework/tool-utils$' '^@fluid-private/test-end-to-end-tests$' '^@fluid-internal/test-snapshots$'— passed.packages\dds\sequence, withMOCHA_SPEC=lib\test\snapshotFormat.spec.js,npm run test:mocha:esm -- --reporter dot— 65 passed, including serialized omission of the legacy flag and clearing a recorded flat setting.packages\dds\sequence, withMOCHA_SPEC=lib\test\fuzz\sharedString.snapshotFormat.fuzz.spec.jsandFUZZ_TEST_COUNT=100,npm run test:mocha:esm -- --reporter dot— 400 passed (100 seeds per workload).packages\test\test-end-to-end-tests, withMOCHA_SPEC=lib\test\sharedStringSnapshotFormat.spec.js,npm run test:realsvc:local -- --compatKind=None --reporter dot— 2 passed, checking the actual attributes blob and summary content through reloads.packages\test\snapshots,npm run test:mocha:esm -- --grep '^Snapshots writes snapshot in correct format$' --reporter dot— 1 passed, with zero mismatches across all current fixture datasets and no special normalization for the new flag.pnpm policy-check --path '^([.]changeset.sticky-shared-string-snapshot-format[.]md|packages.dds.(sequence|merge-tree)|packages.test.test-end-to-end-tests)'— passed.On the preceding fuzz-harness revision, the existing SharedString fuzz workloads also passed 497 cases with 3 pre-existing skips using
npm run test:mocha:esm -- --reporter dotwithMOCHA_SPEC=lib\test\fuzz\sharedString.fuzz.spec.jsandFUZZ_TEST_COUNT=100. The complete DDS fuzz harness passed 41 cases usingnpm run test:mocha:esm -- --grep '^DDS Fuzz Harness' --reporter dotfrompackages\dds\test-dds-utils.Broader CI-readiness and API-report generation checks have not been run locally.