-
Notifications
You must be signed in to change notification settings - Fork 571
improvement(id-compressor): Add resetUnfinalizedCreationRange API and use in CR.replayPendingStates #26784
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
markfields
merged 14 commits into
microsoft:main
from
markfields:id-comp-replaypendingstates
Mar 25, 2026
Merged
improvement(id-compressor): Add resetUnfinalizedCreationRange API and use in CR.replayPendingStates #26784
Changes from 3 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
6719f6c
Add new releaseUnfinalizedCreationRange API
markfields 68d1d58
Refactor takeUnfinalizedCreationRange
markfields 17a7d14
Use releaseUnfinalizedCreationRange in CR.replayPendingStates. Updat…
markfields e620da4
type validation
markfields 741fb9d
typo
markfields de9d066
PR Feedback and comments
markfields 1ace7ed
Delete plan file
markfields db925fb
Merge branch 'main' into id-comp-replaypendingstates
markfields 1bd1bda
Merge branch 'main' into id-comp-replaypendingstates
markfields 681ffbe
Add an e2e test exercising the real reconnect flow
markfields 5c39ed6
test title update
markfields c459d14
PR feedback
markfields 4c4023a
Merge branch 'main' into id-comp-replaypendingstates
markfields 1465456
Test tweaks
markfields File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
63 changes: 63 additions & 0 deletions
63
packages/runtime/id-compressor/replay-id-allocation-approaches.md
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| # Approaches for Deferring ID Allocation Op During Replay | ||
|
|
||
| ## Problem | ||
|
|
||
| During `replayPendingStates`, the container runtime calls `takeUnfinalizedCreationRange` and immediately submits an IdAllocation op. Submitting this op during replay is problematic. We want to defer the allocation so it is included in the next naturally-submitted IdAllocation op instead. | ||
|
|
||
| ## Background | ||
|
|
||
| - `takeNextCreationRange` returns IDs generated since the last range was taken, starting from an internal cursor (`nextRangeBaseGenCount`), and advances the cursor forward. | ||
| - `takeUnfinalizedCreationRange` returns ALL unfinalized IDs (going back to the last finalized cluster), and also advances the cursor forward. | ||
| - `generateCompressedId` does not interact with the range-taking cursor at all -- it only touches `localGenCount`, cluster state, and the normalizer. | ||
|
|
||
| ## Approach B: `releaseUnfinalizedCreationRange` (IdCompressor change) | ||
|
|
||
| Add a new void method to `IIdCompressorCore` / `IdCompressor`: | ||
|
|
||
| ```ts | ||
| public releaseUnfinalizedCreationRange(): void { | ||
| // Reset nextRangeBaseGenCount back to the start of the unfinalized region | ||
| } | ||
| ``` | ||
|
|
||
| The container runtime calls this during replay instead of submitting an op. The next `takeNextCreationRange` call naturally produces a range covering both the old unfinalized IDs and any new IDs generated in the interim. | ||
|
|
||
| ### Pros | ||
|
|
||
| - State tracking is consolidated inside the IdCompressor | ||
| - No merge logic needed -- `takeNextCreationRange` handles everything | ||
| - Only a single range is ever produced, so no ordering/overlap issues | ||
| - `normalizer.getRangesBetween` works correctly for the expanded range | ||
|
|
||
| ### Cons | ||
|
|
||
| - New method on `IIdCompressorCore` (a `@legacy @beta` public interface) | ||
| - `nextRangeBaseGenCount` going backward is a new pattern (currently it only advances) | ||
| - The reserved range is opaque -- caller cannot inspect it for logging/debugging | ||
|
|
||
| ## Approach C: Boolean flag in container runtime (no IdCompressor change) | ||
|
|
||
| Add a boolean flag (`needsUnfinalizedResubmit`) to the container runtime. Set it during replay instead of submitting an op. In `submitIdAllocationOpIfNeeded`, check the flag: | ||
|
|
||
| ```ts | ||
| const idRange = this.needsUnfinalizedResubmit | ||
| ? this._idCompressor.takeUnfinalizedCreationRange() | ||
| : this._idCompressor.takeNextCreationRange(); | ||
| this.needsUnfinalizedResubmit = false; | ||
| ``` | ||
|
|
||
| ### Pros | ||
|
|
||
| - Zero changes to IdCompressor or its public API | ||
| - Uses existing, well-tested methods (`takeUnfinalizedCreationRange`) | ||
| - No new invariants -- `nextRangeBaseGenCount` continues to only advance | ||
| - Simpler to review and reason about | ||
|
|
||
| ### Cons | ||
|
|
||
| - State is split across two components (boolean in container runtime, range state in compressor) | ||
| - Container runtime must know about the distinction between the two take methods (though it already does today) | ||
|
|
||
| ## Recommendation | ||
|
|
||
| Both approaches are functionally equivalent and correct. Approach C is the lower-risk path (no API change, uses existing methods). Approach B is the more principled one (compressor owns its own state). The right choice depends on how much the team values keeping the IdCompressor API minimal vs. consolidating state management. |
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
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
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
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.