You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat(serialization): add owned Arc buffer codec and copier - #11463
ArcBuffer gains a built-in codec that preserves source ownership and contents across repeated serialization, and a copier that acquires independent pins over the referenced bytes. Reader<TInput>.ReadOwnedBuffer(int) centralizes owned payload reads: nonempty Arc input acquires slice pins, other inputs copy into available pooled-page capacity, and a zero-length read returns owner-free ArcBuffer.Empty without advancing. The codec delegates to this reader API.
This PR contains only the six-file serialization delta: codec/copier, owned-read method and Arc slicing helper, focused serialization/ownership tests, ownership-aware built-in codec test discovery, and generated API additions. General buffer and reader correctness fixes and raw lifetime tests were split into #11474, which has merged. This branch is rebased onto its main merge commit 42682376d80e1176a952ba13aa2de25a307b576e; those fixes are no longer part of this PR's diff.
Originally extracted from #10693, this layer serves independently owned pooled-byte serialization. Durable Messaging's GC-owned byte[] envelope payloads require no dependency on it. Main's page-pool policy is preserved; RPC lifetimes and retention policy remain separate concerns.
Making default/Empty a supported value means First is legitimately null for a valid ArcBuffer (as the new tests assert), but the public First field and constructor parameter still advertise non-nullable ArcBufferPage. Nullable-aware consumers can therefore dereference ArcBuffer.Empty.First without a warning. Please update the public nullability contract (and regenerate the API surface) so owner-free buffers expose ArcBufferPage?.
Empty makes First == null a valid public state, but First and the constructor parameter still expose non-nullable ArcBufferPage. Nullable-aware callers therefore receive no warning before dereferencing ArcBuffer.Empty.First. Change both contracts to ArcBufferPage? and regenerate the API surface.
Consume exact remaining page capacity before allocating
Requesting exactly 4096 bytes causes ArcBufferWriter.GetSpan to allocate whenever the current page has exactly 4096 bytes left (sizeHint >= WriteCapacity). As a result, this copy path leaves one quarter of each 16 KiB pooled page unused and allocates roughly 33% more pages for large payloads. Obtain the current span first and cap the read size afterward so exact remaining capacity is consumed.
The current-main baseline is commit 42682376d8 and uses the same reviewed coverage matrix.
Coverage combines every CI test matrix job, including providers, CodeGen, .NET 8/10, Linux, Windows, and macOS, using canonical physical source and branch identities.
The comparison remains report-only while normal line and branch variance is calibrated.
Empty makes a null First part of the valid public contract, but ArcBuffer.First and the constructor's first parameter are still declared non-nullable (and the generated API surface preserves that annotation). Nullable-aware consumers can therefore dereference ArcBuffer.Empty.First without a warning and get a NullReferenceException. Please annotate the page as ArcBufferPage? throughout the public and dependent internal API, then regenerate the API surface.
The disposed-state guard is only effective for methods which call ThrowIfPinnedPages. After Dispose() nulls the page fields, AdvanceReader(0), PeekSlice(0), and ConsumeSlice(0) still bypass this guard and dereference _readPage, producing NullReferenceException instead of the newly established ObjectDisposedException behavior. Add a shared disposed check to these public entry points as well.
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
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.
ArcBuffergains a built-in codec that preserves source ownership and contents across repeated serialization, and a copier that acquires independent pins over the referenced bytes.Reader<TInput>.ReadOwnedBuffer(int)centralizes owned payload reads: nonempty Arc input acquires slice pins, other inputs copy into available pooled-page capacity, and a zero-length read returns owner-freeArcBuffer.Emptywithout advancing. The codec delegates to this reader API.This PR contains only the six-file serialization delta: codec/copier, owned-read method and Arc slicing helper, focused serialization/ownership tests, ownership-aware built-in codec test discovery, and generated API additions. General buffer and reader correctness fixes and raw lifetime tests were split into #11474, which has merged. This branch is rebased onto its main merge commit
42682376d80e1176a952ba13aa2de25a307b576e; those fixes are no longer part of this PR's diff.Originally extracted from #10693, this layer serves independently owned pooled-byte serialization. Durable Messaging's GC-owned
byte[]envelope payloads require no dependency on it. Main's page-pool policy is preserved; RPC lifetimes and retention policy remain separate concerns.Microsoft Reviewers: Open in CodeFlow