feat(container-runtime): add groupedOpCount to grouped batch metadata#27213
Conversation
Expose the inner op count on the metadata of grouped batch envelope messages so wire-level consumers (e.g. Word telemetry) can record batch sizes without parsing the grouped batch contents. Set on: - the envelope produced by groupBatch - the empty-grouped-batch placeholder (value 0) - the final chunk of a chunked grouped batch, so the count survives chunking. Intermediate chunks remain unchanged. Compression preserves metadata, so compressed grouped batches carry the field through unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Hi! Thank you for opening this PR. Want me to review it? Based on the diff (39 lines, 5 files), I've queued these reviewers:
Toggle the reviewer checkboxes above to adjust, then tick the box below to start:
|
- Add splitter unit test asserting groupedOpCount lands only on the last chunk and survives reassembly via originalMetadata. - Inline the metadata read in splitSingletonBatchMessage to match how the batch flag is read; the typeof guard was unnecessary since the metadata field is already typed as Record<string, unknown>. - Extend IBatchMetadata.groupedOpCount JSDoc to enumerate observable values (absent / 0 / N). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Escape `>` in `(N > 0)` to satisfy tsdoc-escape-greater-than, and unwrap the continuation line to satisfy jsdoc/check-indentation.
Stashed-state back-compat: optional/additive field, safely ignored by old runtimes; new runtimes are unaffected by old stashes. Advisory-only: consumed by off-runtime telemetry; the runtime does not validate inbound `groupedOpCount` against the actual inner op count.
Add a one-line `groupedOpCount` round-trip assertion in opCompressor.spec.ts mirroring the existing `flag` metadata pattern, so a future OpCompressor refactor that drops generic metadata is caught by the test suite. Document on IBatchMetadata.groupedOpCount that the field is advisory-only: the runtime does not validate inbound values against actual inner op count; it is consumed exclusively by off-runtime telemetry.
Replace the splitter comment's "mirroring batch flag" hand-wave with the real reason for last-chunk-only stamping: chunks carry payload parts, not ops, so per-chunk stamping would let observers double-count. Tighten the IBatchMetadata JSDoc to capture the stronger invariant — the field is always recomputed at outbound time (groupBatch reads batch.messages.length, createEmptyGroupedBatch always writes 0, the chunked path reads from a freshly-grouped envelope), never propagated from stashed pending state. Resubmitted batches with squashed/dropped/ added ops produce a fresh count matching the actual outbound size. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a new optional groupedOpCount wire-metadata field for grouped batch envelopes so downstream telemetry can observe grouped batch sizes without parsing grouped contents.
Changes:
- Stamp
groupedOpCounton grouped batch envelopes and empty grouped-batch placeholders inOpGroupingManager. - Preserve
groupedOpCounton the final chunk when a grouped batch is chunked inOpSplitter. - Add/update tests covering grouping, chunking/reassembly, and compression metadata preservation.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/runtime/container-runtime/src/test/opLifecycle/opSplitter.spec.ts | Adds coverage for preserving groupedOpCount on the last chunk and after reassembly. |
| packages/runtime/container-runtime/src/test/opLifecycle/opCompressor.spec.ts | Verifies compression keeps groupedOpCount in message metadata. |
| packages/runtime/container-runtime/src/test/opLifecycle/OpGroupingManager.spec.ts | Updates grouping tests to assert groupedOpCount on grouped and empty grouped batches. |
| packages/runtime/container-runtime/src/opLifecycle/opSplitter.ts | Copies groupedOpCount onto the final chunk’s envelope metadata. |
| packages/runtime/container-runtime/src/opLifecycle/opGroupingManager.ts | Stamps groupedOpCount when creating grouped and empty grouped batch metadata. |
| packages/runtime/container-runtime/src/metadata.ts | Documents and types the new groupedOpCount metadata field. |
Old runtimes that predate this field also produce grouped batch envelopes with absent groupedOpCount, so absence cannot be read as definitively "not a grouped batch envelope." Telemetry consumers should treat absence as ambiguous until rollout is complete and fall back to parsing envelope contents if a precise count is required. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The chunked last-chunk envelope carries { batch, groupedOpCount } but not
batchId. With groupedOpCount now stamped, the prior "passively missing"
omission becomes a load-bearing selective-forwarding choice. batchId is
restored on the reassembled message via originalMetadata for runtime
dedup; no wire-level consumer reads it pre-reassembly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Deep ReviewReviewed commit Readiness: 10/10 — READY Ready for sign-off. Small, well-scoped additive change exposing Context for Reviewers
For human reviewer
Review history (7 prior reviews)
|
Description
Adds a
groupedOpCountfield to the metadata of grouped batch envelope messages, exposing the number of inner ops in the batch on the wire. This lets wire-level consumers (Word telemetry in particular) record batch sizes without having to parse the grouped batch contents.Fixes AB#71749.
The field is set on:
OpGroupingManager.groupBatch).OpGroupingManager.createEmptyGroupedBatch, value0).OpSplitter.splitSingletonBatchMessage), so the count survives chunking. Intermediate chunks remain unchanged, mirroring how the existingbatchflag is preserved only on the final chunk.Compression preserves message metadata as-is, so compressed (non-chunked) grouped batches carry the field through unchanged with no additional code.
IBatchMetadatais internal tocontainer-runtimeand not in any API report, so this is not a public API change.Reviewer Guidance
The review process is outlined on this wiki page.
OpGroupingManagerunit tests assert the new field on both the grouped envelope and the empty-grouped-batch placeholder.opSplitter.spec.tshas a newPropagates groupedOpCount onto the last chunk onlytest asserting intermediate chunks carry no metadata, the last chunk's envelope carries{ batch, groupedOpCount }, and reassembly viaprocessChunkrestores the field on the reconstructed message.