refactor(container-runtime): structured return types for serializeOp and getLocalState#26541
Conversation
…Op and getLocalState
Change `serializeOp()` to return `{ content: string }` instead of a raw
string, and `PendingStateManager.getLocalState()` to return
`{ pending: IPendingLocalState }` instead of a bare `IPendingLocalState`.
These structured return types make it straightforward to extend these
functions with additional metadata in the future without further
signature changes.
Co-Authored-By: anthony-murphy <anthony.murphy@microsoft.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/azp run Build - api-markdown-documenter, Build - benchmark-tool, Build - build-common, Build - build-tools, Build - client packages, Build - common-utils, Build - eslint-config-fluid, Build - eslint-plugin-fluid, Build - protocol-definitions, Build site |
|
/azp run Build - test-tools, repo-policy-check, server-gitrest, server-gitssh, server-historian, server-routerlicious |
|
Commenter does not have sufficient privileges for PR 26541 in repo microsoft/FluidFramework |
1 similar comment
|
Commenter does not have sufficient privileges for PR 26541 in repo microsoft/FluidFramework |
|
/azp run Build - api-markdown-documenter, Build - benchmark-tool, Build - build-common, Build - build-tools, Build - client packages, Build - common-utils, Build - eslint-config-fluid, Build - eslint-plugin-fluid, Build - protocol-definitions, Build site |
|
/azp run Build - test-tools, repo-policy-check, server-gitrest, server-gitssh, server-historian, server-routerlicious |
|
Azure Pipelines successfully started running 1 pipeline(s). |
1 similar comment
|
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
Refactors container-runtime op serialization and pending state plumbing to return structured objects instead of raw values, enabling future extension (e.g., adding staging-mode metadata) without another broad mechanical signature change.
Changes:
- Updated
serializeOp()to return{ content: string }and adjusted all call sites/tests to use.content. - Updated
PendingStateManager.getLocalState()to return{ pending: IPendingLocalState }and adjusted all call sites/tests to use.pending. - Updated runtime pending-state assembly to consume the new
getLocalState()shape.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| packages/runtime/container-runtime/src/opLifecycle/opSerialization.ts | Changes serializeOp() to return a structured object { content }. |
| packages/runtime/container-runtime/src/opLifecycle/outbox.ts | Adapts outbound message creation to use serializeOp(...).content. |
| packages/runtime/container-runtime/src/opLifecycle/batchManager.ts | Updates rollback telemetry payload to use serializeOp(...).content. |
| packages/runtime/container-runtime/src/pendingStateManager.ts | Wraps local pending state return value as { pending: ... } and updates stored op content to use .content. |
| packages/runtime/container-runtime/src/containerRuntime.ts | Destructures { pending } from getLocalState() when building IPendingRuntimeState. |
| packages/runtime/container-runtime/src/test/opLifecycle/outbox.spec.ts | Updates test helper serialization usage to .content. |
| packages/runtime/container-runtime/src/test/opLifecycle/opSerialization.spec.ts | Updates assertions for the new { content } return shape. |
| packages/runtime/container-runtime/src/test/pendingStateManager.spec.ts | Updates pending state access paths to .pending.pendingStates / .pending. |
| packages/runtime/container-runtime/src/test/containerRuntime.spec.ts | Updates pending state assertions to .pending.pendingStates. |
Fix line-length formatting issues flagged by biome check. Co-Authored-By: anthony-murphy <anthony.murphy@microsoft.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
After the latest push (formatting fixes for biome), the following Azure Pipelines need to be triggered. Please copy and post these commands: |
|
/azp run Build - client packages |
|
No pipelines are associated with this pull request. |
|
/azp run repo-policy-check |
|
No pipelines are associated with this pull request. |
|
/azp run Build - api-markdown-documenter, Build - benchmark-tool, Build - build-common, Build - build-tools, Build - client packages, Build - common-utils, Build - eslint-config-fluid, Build - eslint-plugin-fluid, Build - protocol-definitions, Build site |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run Build - test-tools, repo-policy-check, server-gitrest, server-gitssh, server-historian, server-routerlicious |
|
Azure Pipelines successfully started running 1 pipeline(s). |
…te shape
Update three proxy mocks in containerRuntime.spec.ts to return
`{ pending: { pendingStates } }` instead of the old `IPendingLocalState`
shape. Remove unused IPendingLocalState import.
Co-Authored-By: anthony-murphy <anthony.murphy@microsoft.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
After the latest push (mock fixes for review feedback), the following Azure Pipelines need to be triggered. Please copy and post these commands: |
|
/azp run Build - api-markdown-documenter, Build - benchmark-tool, Build - build-common, Build - build-tools, Build - client packages, Build - common-utils, Build - eslint-config-fluid, Build - eslint-plugin-fluid, Build - protocol-definitions, Build site |
|
/azp run Build - test-tools, repo-policy-check, server-gitrest, server-gitssh, server-historian, server-routerlicious |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run Build - api-markdown-documenter, Build - benchmark-tool, Build - build-common, Build - build-tools, Build - client packages, Build - common-utils, Build - eslint-config-fluid, Build - eslint-plugin-fluid, Build - protocol-definitions, Build site |
|
/azp run Build - test-tools, repo-policy-check, server-gitrest, server-gitssh, server-historian, server-routerlicious |
|
Azure Pipelines successfully started running 1 pipeline(s). |
1 similar comment
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
|
||
| public getLocalState(snapshotSequenceNumber?: number): IPendingLocalState { | ||
| public getLocalState(snapshotSequenceNumber?: number): { | ||
| pending: IPendingLocalState; |
There was a problem hiding this comment.
Do we really need the extra hierarchy here? Why not just add the next thing to IPendingLocalState?
There was a problem hiding this comment.
IPendingLocalState is a serializable object. i want to pass non-serializable state along with it, specifically the list of handles referenced from the pending state for un-attached things
| const outboundMessages = localBatch.messages.map<OutboundBatchMessage>( | ||
| ({ runtimeOp, ...message }) => ({ | ||
| contents: serializeOp(runtimeOp), | ||
| contents: serializeOp(runtimeOp).content, |
There was a problem hiding this comment.
Bugs me that we are so inconsistent between content and contents`. That ship has sailed though, you just gotta pick one I guess.
Although, most usages I see in this PR are contents, I think all except for in IPendingMessage. Might be worth asking Claude to evaluate how close we are to converging on contents without making breaking changes.
Have we shipped anything using IPendingMessage as a durable/code format yet?
There was a problem hiding this comment.
nothing durable yet AFAIK
There was a problem hiding this comment.
It's mostly principled, not random:
contents = the payload field of a protocol message or envelope (wire format)
- IDocumentMessage.contents, ISequencedDocumentMessage.contents — the wire protocol origin
- IEnvelope.contents, ISignalEnvelope.contents, TypedContainerRuntimeMessage.contents, IChunkedOp.contents
- Rule: if it's a wrapper/envelope carrying something, use contents
content = leaf data (blob bytes) or typed payload within a TypedMessage
- ISummaryBlob.content, IBlob.content (git), IOdspSummaryBlob.content — raw bytes
- TypedMessage.content, ISignalMessageBase.content, INack.content — typed inner payload
- Rule: if it's the actual data or a strongly-typed leaf field, use content
i have no idea how true this is
PRISM ReviewReadiness: 9/10 — READY Clean mechanical refactor wrapping FindingsNone. Style and naming preferences (e.g., anonymous vs named return types, Path to Ready
Context for ReviewersThis is the first half of a two-part change. PR #26475 will add |
…and getLocalState (microsoft#26541) ## Summary - Change `serializeOp()` to return `{ content: string }` instead of a raw string - Change `PendingStateManager.getLocalState()` to return `{ pending: IPendingLocalState }` instead of a bare `IPendingLocalState` - Update all callers and tests to use the new structured return types These structured return types make it straightforward to extend these functions with additional metadata in the future without further signature changes. Specifically, the staging mode pending state work in microsoft#26475 needs to add `stagedHandleCache` to both return types — by landing the structural change first, that PR can focus on the substantive feature logic without a large mechanical diff touching many test files. ## Test plan - [x] `build:esnext` passes for `@fluidframework/container-runtime` and all dependencies - [ ] CI validation 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: anthony-murphy-agent <anthony-murphy-agent@users.noreply.github.com> Co-authored-by: anthony-murphy <anthony.murphy@microsoft.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
serializeOp()to return{ content: string }instead of a raw stringPendingStateManager.getLocalState()to return{ pending: IPendingLocalState }instead of a bareIPendingLocalStateThese structured return types make it straightforward to extend these functions with additional metadata in the future without further signature changes. Specifically, the staging mode pending state work in #26475 needs to add
stagedHandleCacheto both return types — by landing the structural change first, that PR can focus on the substantive feature logic without a large mechanical diff touching many test files.Test plan
build:esnextpasses for@fluidframework/container-runtimeand all dependencies🤖 Generated with Claude Code