feat(counter): implement reSubmitSquashed hook (identity transform)#27404
feat(counter): implement reSubmitSquashed hook (identity transform)#27404anthony-murphy wants to merge 1 commit into
Conversation
|
Hi! Thank you for opening this PR. Want me to review it? Based on the diff (10 lines, 1 files), I've queued these reviewers:
How this works
|
|
Closing: this implements |
Deep ReviewReviewed commit Readiness: 8/10 — ALMOST READY The 10-line Path to Ready
Context for Reviewers
For human reviewer
|
| */ | ||
| protected override reSubmitSquashed(content: unknown, localOpMetadata: unknown): void { | ||
| this.reSubmitCore(content, localOpMetadata); | ||
| } |
There was a problem hiding this comment.
Deep Review: No test exercises the path this override exists to protect. The new method only matters when Fluid.SharedObject.AllowStagingModeWithoutSquashing=false — in that branch the base SharedObject.reSubmitSquashed (packages/dds/shared-object-base/src/sharedObject.ts:490-502) calls throwUnsupported("reSubmitSquashed"). The PR adds 10 lines, 0 deletions, touches zero test files. Existing packages/dds/counter/src/test/counter.spec.ts:244-306 covers reconnection resubmit and counter.fuzz.spec.ts:20-31 covers rebase fuzzing, but packages/dds/counter/src/test contains no AllowStagingModeWithoutSquashing reference, and packages/test/local-server-tests/src/test/stagingMode.spec.ts:301-303 pins the flag to true.
Precedent: PR #25771 added the rollback hook with UT + fuzz + stress coverage. The urgency here is lower (this is a one-line identity delegation vs. novel arithmetic), which is why this is polish rather than blocking — but the contract it asserts is exactly what motivates the PR, so pinning it pays off when the upcoming flag flip lands.
Suggested test in packages/dds/counter/src/test/counter.spec.ts:
- Set
Fluid.SharedObject.AllowStagingModeWithoutSquashing=false. - Queue multiple pending increments, including a negative.
- Trigger a squashed resubmit.
- Assert every increment is resubmitted unchanged.
Alternative: wire SharedCounter into packages/test/local-server-tests/src/test/stagingMode.spec.ts with the flag flipped off. Either pins the contract so a future refactor that drops override or changes the base-class default fails CI.
| * intent to add that amount to the counter. No increment is "subsumed" by a later one (a later | ||
| * `+3` doesn't cancel an earlier `+5`), so the squash on resubmit is the identity transform: | ||
| * each pending increment is resubmitted unchanged. | ||
| */ |
There was a problem hiding this comment.
Deep Review: The doc comment diverges from the convention established for adjacent overrides in this same class. applyStashedOp (counter.ts:197-199) uses {@inheritdoc @fluidframework/shared-object-base#SharedObjectCore.applyStashedOp}, and rollback (counter.ts:220-223, added in PR #25771, approved by ChumpChief) uses {@inheritDoc @fluidframework/shared-object-base#SharedObject.rollback} plus @sealed. The new reSubmitSquashed carries only the free-form rationale paragraph — no {@inheritDoc}, no @sealed.
SharedString/Sequence's equivalent override (packages/dds/sequence/src/sequence.ts:796-798) also omits both tags, so this is not a repo-wide convention — but it is the local convention for this class set by the most recent precedent on this exact file.
Keep the rationale paragraph (it documents the Counter-specific commutative/additive justification that an inherit-doc alone wouldn't carry). Add {@inheritDoc @fluidframework/shared-object-base#SharedObject.reSubmitSquashed} and @sealed so the override matches the adjacent rollback.
Description
Implements
SharedObjectCore.reSubmitSquashedonSharedCounteras the identity transform — each pending increment is resubmitted unchanged viareSubmitCore.Why
Counter increments are commutative and additive (a later
+3never cancels an earlier+5), so the squash on resubmit is the identity transform. The basereSubmitSquashedfalls back toreSubmitCoreonly while theFluid.SharedObject.AllowStagingModeWithoutSquashingflag is true; otherwise it throws. Explicitly opting in protects this DDS from breaking when the flag is flipped.Notes
Prep for upcoming DDS-wide staging-mode squash work.