Skip to content

Add ArcBuffer support to Orleans serialization#10066

Merged
ReubenBond merged 1 commit into
dotnet:mainfrom
ReubenBond:split/serialization-buffer-fixes
Apr 30, 2026
Merged

Add ArcBuffer support to Orleans serialization#10066
ReubenBond merged 1 commit into
dotnet:mainfrom
ReubenBond:split/serialization-buffer-fixes

Conversation

@ReubenBond

@ReubenBond ReubenBond commented Apr 30, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds ArcBuffer input support for serialization readers, including multi-page reads, position/length tracking, skip, and fork/resume behavior.
  • Adds Serializer and Serializer<T> overloads for deserializing directly from ArcBuffer.
  • Adds Writer.Create(ArcBufferWriter, ...) via a wrapper which does not dispose the underlying ArcBufferWriter.
  • Updates serialization test helpers and adds focused ArcBufferWriter serialization tests for multi-page payloads and serializer round-trips.
Microsoft Reviewers: Open in CodeFlow

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ReubenBond ReubenBond changed the title Fix serialization buffer writer edge cases Add ArcBuffer support to Orleans serialization Apr 30, 2026
@ReubenBond ReubenBond requested a review from Copilot April 30, 2026 04:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends Orleans’ serialization buffer plumbing to support ArcBuffer as an input source for readers and deserializers, enabling multi-page reads and round-trips directly over ArcBuffer/ArcBufferWriter.

Changes:

  • Added Reader.Create(ArcBuffer, ...) and an ArcBufferReaderInput adaptor for multi-page reading/positioning/skip/fork behavior.
  • Added Serializer/Serializer<T> overloads to deserialize directly from ArcBuffer.
  • Added Writer.Create(ArcBufferWriter, ...) using a wrapper which prevents disposing the underlying ArcBufferWriter, plus new unit tests and testkit updates.
Show a summary per file
File Description
test/Orleans.Serialization.UnitTests/Buffers/ArcBufferWriterSerializationTests.cs Adds focused tests for multi-page writer/reader and serializer round-trips using ArcBufferWriter + ArcBuffer.
src/Orleans.Serialization/Serializer.cs Adds Deserialize(... ArcBuffer ...) overloads on Serializer and Serializer<T>.
src/Orleans.Serialization/Buffers/Writer.cs Adds Writer.Create(ArcBufferWriter, ...) and ArcBufferWriterWrapper to avoid disposing the underlying writer.
src/Orleans.Serialization/Buffers/Reader.cs Adds Reader.Create(ArcBuffer, ...) and integrates ArcBufferReaderInput into reader fast paths and navigation logic.
src/Orleans.Serialization/Buffers/Adaptors/BufferSliceReaderInput.cs Introduces ArcBufferReaderInput adaptor implementation.
src/Orleans.Serialization.TestKit/FieldCodecTester.cs Updates serialization test helper to produce/format/deserialize via ArcBufferWriter + ArcBuffer.

Copilot's findings

Comments suppressed due to low confidence (2)

src/Orleans.Serialization/Serializer.cs:889

  • This new public Deserialize(ArcBuffer source) overload (on Serializer<T>) changes the Orleans.Serialization public API surface, but src/api/Orleans.Serialization/Orleans.Serialization.cs does not currently include it. Update the generated API surface file to reflect this addition.
        public T Deserialize(ArcBuffer source)
        {
            using var session = _sessionPool.GetSession();
            var reader = Reader.Create(source, session);
            var field = reader.ReadFieldHeader();
            return _codec.ReadValue(ref reader, field);
        }

src/Orleans.Serialization/Buffers/Adaptors/BufferSliceReaderInput.cs:125

  • ArcBufferReaderInput is in the Orleans.Serialization.Buffers.Adaptors namespace, but it references ArcBuffer and ArcBufferPage which are declared in Orleans.Serialization.Buffers. This file does not import that namespace, so these type references will not resolve and the project will fail to compile. Add a using Orleans.Serialization.Buffers; (or fully-qualify the types) so ArcBuffer/ArcBufferPage are in scope.
public struct ArcBufferReaderInput(in ArcBuffer slice)
{
    private readonly ArcBuffer _slice = slice;
    private ArcBufferPage _page = slice.First;
    private int _position;
  • Files reviewed: 6/6 changed files
  • Comments generated: 5

Comment on lines +111 to +124
/// Disposing a <see cref="Writer{TBufferWriter}"/> over this wrapper does not dispose the underlying <see cref="ArcBufferWriter"/>.
/// </remarks>
/// <param name="bufferWriter">The wrapped buffer writer.</param>
public readonly struct ArcBufferWriterWrapper(ArcBufferWriter bufferWriter) : IBufferWriter<byte>
{
/// <inheritdoc/>
public void Advance(int count) => ((IBufferWriter<byte>)bufferWriter).Advance(count);

/// <inheritdoc/>
public Memory<byte> GetMemory(int sizeHint = 0) => bufferWriter.GetMemory(sizeHint);

/// <inheritdoc/>
public Span<byte> GetSpan(int sizeHint = 0) => bufferWriter.GetSpan(sizeHint);
}

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ArcBufferWriterWrapper is a new public type, but the committed API baseline in src/api/Orleans.Serialization/Orleans.Serialization.cs does not include it. Update the generated API surface file so this new public type is represented.

Copilot uses AI. Check for mistakes.
Comment on lines +197 to +204
/// <summary>
/// Creates a reader for the provided buffer.
/// </summary>
/// <param name="input">The input.</param>
/// <param name="session">The session.</param>
/// <returns>A new <see cref="Reader{TInput}"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Reader<ArcBufferReaderInput> Create(ArcBuffer input, SerializerSession session) => new(new ArcBufferReaderInput(in input), session, 0);

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reader.Create(ArcBuffer, ...) is a new public API, but the committed API baseline file (src/api/Orleans.Serialization/Orleans.Serialization.cs) does not currently list this overload. Update the generated API surface file to include this new method.

Copilot uses AI. Check for mistakes.
/// Initializes a new instance of the <see cref="ArcBufferReaderInput"/> type.
/// </remarks>
/// <param name="slice">The underlying buffer.</param>
public struct ArcBufferReaderInput(in ArcBuffer slice)

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ArcBufferReaderInput is a new public type, but it is not present in the committed API baseline (src/api/Orleans.Serialization/Orleans.Serialization.cs). Update the generated API surface file so this type is captured for API review.

This issue also appears on line 121 of the same file.

Suggested change
public struct ArcBufferReaderInput(in ArcBuffer slice)
internal struct ArcBufferReaderInput(in ArcBuffer slice)

Copilot uses AI. Check for mistakes.
Comment on lines +417 to +424
public T Deserialize<T>(ArcBuffer source)
{
using var session = _sessionPool.GetSession();
var reader = Reader.Create(source, session);
var codec = session.CodecProvider.GetCodec<T>();
var field = reader.ReadFieldHeader();
return codec.ReadValue(ref reader, field);
}

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new public Deserialize<T>(ArcBuffer source) overload changes the Orleans.Serialization public API surface, but src/api/Orleans.Serialization/Orleans.Serialization.cs does not currently include it. Update the generated API surface file so the baseline matches the new API.

This issue also appears on line 883 of the same file.

Copilot uses AI. Check for mistakes.
Comment on lines +33 to +41
/// <summary>
/// Creates a writer which writes to the specified destination.
/// </summary>
/// <param name="destination">The destination.</param>
/// <param name="session">The session.</param>
/// <returns>A new <see cref="Writer{TBufferWriter}"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Writer<ArcBufferWriterWrapper> Create(ArcBufferWriter destination, SerializerSession session) => new(new(destination), session);

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Writer.Create(ArcBufferWriter, ...) adds new public API surface in a packable src/ project, but src/api/Orleans.Serialization/Orleans.Serialization.cs does not currently include this overload. Update the generated API surface file to reflect the new API.

Copilot uses AI. Check for mistakes.
@ReubenBond ReubenBond marked this pull request as ready for review April 30, 2026 13:52
@ReubenBond ReubenBond added this pull request to the merge queue Apr 30, 2026
Merged via the queue into dotnet:main with commit 1fde981 Apr 30, 2026
66 checks passed
@ReubenBond ReubenBond deleted the split/serialization-buffer-fixes branch April 30, 2026 14:22
@github-actions github-actions Bot locked and limited conversation to collaborators May 31, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants