feat(container-loader): add snapshot history for flat checkpoint storage#26400
Draft
anthony-murphy-agent wants to merge 5 commits intomicrosoft:mainfrom
Draft
feat(container-loader): add snapshot history for flat checkpoint storage#26400anthony-murphy-agent wants to merge 5 commits intomicrosoft:mainfrom
anthony-murphy-agent wants to merge 5 commits intomicrosoft:mainfrom
Conversation
…int storage Add a .history subtree to summaries that preserves historical document states as checkpoint handles. Each checkpoint uses a loading group for delay-loading and references only .app and .protocol (not .history) to enable independent GC. Key components: - HistoryTreeStorageService: intercepts summary uploads to add .history tree - SnapshotHistoryManager: read-side API for enumerating/looking up checkpoints - Config-gated via Fluid.Container.enableSnapshotHistory and related flags - All isCombinedAppAndProtocolSummary call sites updated to accept .history Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-Authored-By: anthony-murphy <anthony.murphy@microsoft.com>
…feature Exercise the full snapshot history flow through a real local server: create container, edit, summarize (writes .history), load from snapshot, and verify checkpoints. Tests use a seed summary with summarizeProtocolTree2 to establish the .app/.protocol snapshot structure needed by the local server before enabling history-enabled summaries. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-Authored-By: anthony-murphy <anthony.murphy@microsoft.com>
- Clarify that `pinned` field is future-proofing, not yet used - Add template literal return types to checkpointGroupId and checkpointKey Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-Authored-By: anthony-murphy <anthony.murphy@microsoft.com>
…oadCheckpoint Promote snapshotHistory to the alpha API surface so consumers use asLegacyAlpha(container).snapshotHistory instead of unsafe casts. Add loadCheckpoint() method to SnapshotHistoryManager for fetching historical checkpoint data via the driver's getSnapshot API. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-Authored-By: anthony-murphy <anthony.murphy@microsoft.com>
…inline literal types
Address review feedback: use `fluid-history-${number}` and `cp-${number}` directly
instead of `${typeof constant}${number}` for better readability.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: anthony-murphy <anthony.murphy@microsoft.com>
Contributor
Author
|
Pipeline checks are missing (fork PR). Please post the following commands to trigger them: |
Contributor
There was a problem hiding this comment.
Pull request overview
This pull request adds snapshot history functionality to the Fluid Framework, allowing the preservation of historical document states as checkpoints within a .history subtree in the summary tree.
Changes:
- Implements
HistoryTreeStorageServiceto intercept summary uploads and manage checkpoint creation, retention, and storage - Implements
SnapshotHistoryManageras a read-side API for enumerating and loading historical checkpoints - Updates
isCombinedAppAndProtocolSummaryacross all call sites to accept.historyas an optional root tree - Adds comprehensive unit and integration tests
- Feature-gated via
Fluid.Container.enableSnapshotHistoryand related configuration flags
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
packages/loader/container-loader/src/snapshotHistory.ts |
Core implementation of HistoryTreeStorageService and SnapshotHistoryManager classes, plus helper functions for parsing checkpoint index |
packages/loader/container-loader/src/container.ts |
Integrates snapshot history into Container, exposes snapshotHistory property on ContainerAlpha interface, parses and initializes checkpoints on load |
packages/loader/container-loader/src/containerStorageAdapter.ts |
Creates HistoryTreeStorageService in the storage service middleware chain, exposes it via historyStorageService property |
packages/loader/container-loader/src/utils.ts |
Updates isCombinedAppAndProtocolSummary calls to accept .history as optional tree |
packages/loader/container-loader/src/index.ts |
Exports snapshot history types and classes |
packages/loader/driver-utils/src/treeConversions.ts |
Updates convertSummaryTreeToSnapshotITree to include .history tree when present |
packages/drivers/*/ |
Updates all driver create-new paths to accept .history as optional root tree |
packages/loader/container-loader/src/test/snapshotHistory.spec.ts |
Comprehensive unit tests for HistoryTreeStorageService, parseHistoryIndex, and SnapshotHistoryManager |
packages/test/local-server-tests/src/test/snapshotHistory.spec.ts |
Integration tests verifying end-to-end functionality with local server |
packages/loader/container-loader/api-report/container-loader.legacy.alpha.api.md |
API surface additions for snapshot history feature |
Comment on lines
+26
to
+27
| ...((summaryTree as ISummaryTree).tree[".history"] !== undefined | ||
| ? ([[".history", (summaryTree as ISummaryTree).tree[".history"]]] as [string, ISummaryTree["tree"][string]][]) |
There was a problem hiding this comment.
The type assertion (summaryTree as ISummaryTree) is redundant since summaryTree is already typed as ISummaryTree from the function parameter. The code can directly access summaryTree.tree[".history"] without the cast.
Suggested change
| ...((summaryTree as ISummaryTree).tree[".history"] !== undefined | |
| ? ([[".history", (summaryTree as ISummaryTree).tree[".history"]]] as [string, ISummaryTree["tree"][string]][]) | |
| ...(summaryTree.tree[".history"] !== undefined | |
| ? ([[".history", summaryTree.tree[".history"]]] as [string, ISummaryTree["tree"][string]][]) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
.historysubtree to the summary tree that preserves historical document states as checkpoint handlesISummaryTreewith its owngroupIdfor delay-loading, containing handles to.appand.protocolonly (not.history) to enable independent GCindexblob provides cheap enumeration of all available checkpointsHistoryTreeStorageServiceintercepts summary uploads to manage the.historytreeSnapshotHistoryManagerprovides a read-side API for enumerating and looking up checkpointsFluid.Container.enableSnapshotHistoryand related config flagsisCombinedAppAndProtocolSummarycall sites updated to accept.historyas optional root treeTest plan
🤖 Generated with Claude Code