From 340664bb9d2f352ebbf92d0dc722944b33b6a64b Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Sun, 23 Aug 2026 18:11:36 -0700 Subject: [PATCH 1/7] fix(journaling): preserve snapshot reference scopes Reset the Orleans serializer reader session between independently encoded snapshot values while retaining each value's internal aliases and existing wire bytes. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f32c3454-1184-4a8b-81c3-7a9f9b094617 --- .../OrleansBinaryCommandCodecHelpers.cs | 8 ++ ...eansBinaryDurableDictionaryCommandCodec.cs | 4 +- .../OrleansBinaryDurableListCommandCodec.cs | 2 +- .../OrleansBinaryDurableQueueCommandCodec.cs | 2 +- .../OrleansBinaryDurableSetCommandCodec.cs | 2 +- .../OrleansBinaryCommandCodecTests.cs | 128 ++++++++++++++++++ 6 files changed, 141 insertions(+), 5 deletions(-) diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryCommandCodecHelpers.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryCommandCodecHelpers.cs index db4e508e986..dac55c826c7 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryCommandCodecHelpers.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryCommandCodecHelpers.cs @@ -27,4 +27,12 @@ public static T ReadValue(IFieldCodec codec, ref Reader re var field = reader.ReadFieldHeader(); return codec.ReadValue(ref reader, field)!; } + + public static T ReadIndependentValue(IFieldCodec codec, ref Reader reader) + { + var result = ReadValue(codec, ref reader); + // Snapshot values are each encoded with a fresh serializer session. + reader.Session.Reset(); + return result; + } } diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs index 52ca5126bb6..8860ce49666 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs @@ -123,8 +123,8 @@ private void ApplySnapshot(ref Reader reader, IDurableDictionary consumer.Reset(count); for (var i = 0; i < count; i++) { - var key = OrleansBinaryCommandCodecHelpers.ReadValue(keyCodec, ref reader); - var value = OrleansBinaryCommandCodecHelpers.ReadValue(valueCodec, ref reader); + var key = OrleansBinaryCommandCodecHelpers.ReadIndependentValue(keyCodec, ref reader); + var value = OrleansBinaryCommandCodecHelpers.ReadIndependentValue(valueCodec, ref reader); consumer.ApplySet(key, value); } } diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableListCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableListCommandCodec.cs index ba38edf008a..a68d48d0c44 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableListCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableListCommandCodec.cs @@ -156,7 +156,7 @@ private void ApplySnapshot(ref Reader reader, IDurableListComman consumer.Reset(count); for (var i = 0; i < count; i++) { - consumer.ApplyAdd(OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader)); + consumer.ApplyAdd(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader)); } } diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableQueueCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableQueueCommandCodec.cs index 2ab6b34fcfb..e9882426068 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableQueueCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableQueueCommandCodec.cs @@ -113,7 +113,7 @@ private void ApplySnapshot(ref Reader reader, IDurableQueueComma consumer.Reset(count); for (var i = 0; i < count; i++) { - consumer.ApplyEnqueue(OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader)); + consumer.ApplyEnqueue(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader)); } } diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableSetCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableSetCommandCodec.cs index 8b8585b13a3..a938b18fb58 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableSetCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableSetCommandCodec.cs @@ -115,7 +115,7 @@ private void ApplySnapshot(ref Reader reader, IDurableSetCommand consumer.Reset(count); for (var i = 0; i < count; i++) { - consumer.ApplyAdd(OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader)); + consumer.ApplyAdd(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader)); } } } diff --git a/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs b/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs index 89b93d80e6c..b21fe565c98 100644 --- a/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs +++ b/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs @@ -38,6 +38,26 @@ public void DictionaryCodec_AllCommands_RoundTrip() Assert.Empty(consumer.SnapshotItems); } + [Fact] + public void DictionaryCodec_PreChangeSnapshotPayload_ReplaysIndependentReferenceScopes() + { + var codec = new OrleansBinaryDurableDictionaryCommandCodec( + ValueCodec(), + ValueCodec(), + SessionPool); + var items = CreateReferenceItems(); + var payload = CodecTestHelpers.WriteEntry( + writer => codec.WriteSnapshot([new("first", items[0]), new("second", items[1])], writer)); + + Assert.Equal( + "0705400B6669727374204007010203C105E0400D7365636F6E64204007040506C105E0", + Convert.ToHexString(payload)); + + var consumer = new RecordingDictionaryCommandHandler(); + codec.Apply(CodecTestHelpers.ReadBuffer(payload), consumer); + AssertAliases(consumer.SnapshotItems.Select(static item => item.Value)); + } + [Fact] public void ListCodec_AllCommands_RoundTrip() { @@ -67,6 +87,21 @@ public void ListCodec_AllCommands_RoundTrip() consumer.Commands); } + [Fact] + public void ListCodec_PreChangeSnapshotPayload_ReplaysIndependentReferenceScopes() + { + var codec = new OrleansBinaryDurableListCommandCodec( + ValueCodec(), + SessionPool); + var payload = CodecTestHelpers.WriteEntry(writer => codec.WriteSnapshot(CreateReferenceItems(), writer)); + + Assert.Equal("0B05204007010203C105E0204007040506C105E0", Convert.ToHexString(payload)); + + var consumer = new SnapshotCollectionConsumer(); + codec.Apply(CodecTestHelpers.ReadBuffer(payload), consumer); + AssertAliases(consumer.Items); + } + [Fact] public void QueueCodec_AllCommands_RoundTrip() { @@ -92,6 +127,21 @@ public void QueueCodec_AllCommands_RoundTrip() consumer.Commands); } + [Fact] + public void QueueCodec_PreChangeSnapshotPayload_ReplaysIndependentReferenceScopes() + { + var codec = new OrleansBinaryDurableQueueCommandCodec( + ValueCodec(), + SessionPool); + var payload = CodecTestHelpers.WriteEntry(writer => codec.WriteSnapshot(CreateReferenceItems(), writer)); + + Assert.Equal("0705204007010203C105E0204007040506C105E0", Convert.ToHexString(payload)); + + var consumer = new SnapshotCollectionConsumer(); + codec.Apply(CodecTestHelpers.ReadBuffer(payload), consumer); + AssertAliases(consumer.Items); + } + [Fact] public void SetCodec_AllCommands_RoundTrip() { @@ -117,6 +167,21 @@ public void SetCodec_AllCommands_RoundTrip() consumer.Commands); } + [Fact] + public void SetCodec_PreChangeSnapshotPayload_ReplaysIndependentReferenceScopes() + { + var codec = new OrleansBinaryDurableSetCommandCodec( + ValueCodec(), + SessionPool); + var payload = CodecTestHelpers.WriteEntry(writer => codec.WriteSnapshot(CreateReferenceItems(), writer)); + + Assert.Equal("0705204007010203C105E0204007040506C105E0", Convert.ToHexString(payload)); + + var consumer = new SnapshotCollectionConsumer(); + codec.Apply(CodecTestHelpers.ReadBuffer(payload), consumer); + AssertAliases(consumer.Items); + } + [Fact] public void ValueStateAndTcsCodecs_AllCommands_RoundTrip() { @@ -492,4 +557,67 @@ private static void AssertTrailingDataRejected(Action action) var exception = Assert.Throws(action); Assert.Contains("trailing data", exception.Message); } + + private static SnapshotReferenceRecord[] CreateReferenceItems() + { + var first = new byte[] { 1, 2, 3 }; + var second = new byte[] { 4, 5, 6 }; + return + [ + new() { Payload = first, Alias = first }, + new() { Payload = second, Alias = second } + ]; + } + + private static void AssertAliases(IEnumerable items) + { + Assert.Collection( + items, + item => + { + Assert.Equal([1, 2, 3], item.Payload); + Assert.Same(item.Payload, item.Alias); + }, + item => + { + Assert.Equal([4, 5, 6], item.Payload); + Assert.Same(item.Payload, item.Alias); + }); + } +} + +[GenerateSerializer] +internal sealed class SnapshotReferenceRecord +{ + [Id(0)] + public required byte[] Payload { get; init; } + + [Id(1)] + public required byte[] Alias { get; init; } +} + +internal sealed class SnapshotCollectionConsumer : + IDurableListCommandHandler, + IDurableQueueCommandHandler, + IDurableSetCommandHandler +{ + public List Items { get; } = []; + + public void ApplyAdd(SnapshotReferenceRecord item) => Items.Add(item); + + public void ApplySet(int index, SnapshotReferenceRecord item) => throw new NotSupportedException(); + + public void ApplyInsert(int index, SnapshotReferenceRecord item) => throw new NotSupportedException(); + + public void ApplyRemoveAt(int index) => throw new NotSupportedException(); + + public void ApplyClear() => Items.Clear(); + + public void Reset(int capacityHint) => Items.Clear(); + + public void ApplyEnqueue(SnapshotReferenceRecord item) => Items.Add(item); + + public void ApplyDequeue() => throw new NotSupportedException(); + + public void ApplyRemove(SnapshotReferenceRecord item) => throw new NotSupportedException(); } From ede385d57e2f20c6147a1104ee2f35e74c21adb7 Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Mon, 24 Aug 2026 11:13:39 -0700 Subject: [PATCH 2/7] refactor(journaling): use independent serialization roots Pair every encoded value with an explicit independent reader scope, including dictionary keys and values, and remove the shared-scope helper. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f32c3454-1184-4a8b-81c3-7a9f9b094617 --- .../OrleansBinaryCommandCodecHelpers.cs | 20 ++++++------- ...eansBinaryDurableDictionaryCommandCodec.cs | 19 ++++++------ .../OrleansBinaryDurableListCommandCodec.cs | 14 ++++----- .../OrleansBinaryDurableQueueCommandCodec.cs | 6 ++-- .../OrleansBinaryDurableSetCommandCodec.cs | 10 +++---- ...DurableTaskCompletionSourceCommandCodec.cs | 8 ++--- .../OrleansBinaryDurableValueCommandCodec.cs | 4 +-- ...rleansBinaryPersistentStateCommandCodec.cs | 4 +-- .../OrleansBinaryCommandCodecTests.cs | 29 ++++++++++++++++--- 9 files changed, 67 insertions(+), 47 deletions(-) diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryCommandCodecHelpers.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryCommandCodecHelpers.cs index dac55c826c7..36026ca07e3 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryCommandCodecHelpers.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryCommandCodecHelpers.cs @@ -10,7 +10,7 @@ namespace Orleans.Journaling; /// internal static class OrleansBinaryCommandCodecHelpers { - public static void WriteValue( + public static void WriteIndependentValue( IFieldCodec codec, T value, IBufferWriter output, @@ -22,17 +22,17 @@ public static void WriteValue( writer.Commit(); } - public static T ReadValue(IFieldCodec codec, ref Reader reader) - { - var field = reader.ReadFieldHeader(); - return codec.ReadValue(ref reader, field)!; - } - public static T ReadIndependentValue(IFieldCodec codec, ref Reader reader) { - var result = ReadValue(codec, ref reader); - // Snapshot values are each encoded with a fresh serializer session. reader.Session.Reset(); - return result; + try + { + var field = reader.ReadFieldHeader(); + return codec.ReadValue(ref reader, field)!; + } + finally + { + reader.Session.Reset(); + } } } diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs index 8860ce49666..ec63b8659b1 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs @@ -22,12 +22,11 @@ public void WriteSet(TKey key, TValue value, JournalStreamWriter writer) { using var entry = writer.BeginEntry(); var output = entry.Writer; - using var session = sessionPool.GetSession(); - var payloadWriter = Writer.Create(output, session); + var payloadWriter = Writer.Create(output, session: null!); payloadWriter.WriteVarUInt32(SetCommand); - keyCodec.WriteField(ref payloadWriter, 0, typeof(TKey), key); - valueCodec.WriteField(ref payloadWriter, 1, typeof(TValue), value); payloadWriter.Commit(); + OrleansBinaryCommandCodecHelpers.WriteIndependentValue(keyCodec, key, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteIndependentValue(valueCodec, value, output, sessionPool); entry.Commit(); } @@ -39,7 +38,7 @@ public void WriteRemove(TKey key, JournalStreamWriter writer) var payloadWriter = Writer.Create(output, session: null!); payloadWriter.WriteVarUInt32(RemoveCommand); payloadWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteValue(keyCodec, key, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteIndependentValue(keyCodec, key, output, sessionPool); entry.Commit(); } @@ -67,8 +66,8 @@ public void WriteSnapshot(IReadOnlyCollection> items, foreach (var (key, value) in items) { CollectionCodecHelpers.ThrowIfSnapshotItemCountExceeded(count, written); - OrleansBinaryCommandCodecHelpers.WriteValue(keyCodec, key, output, sessionPool); - OrleansBinaryCommandCodecHelpers.WriteValue(valueCodec, value, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteIndependentValue(keyCodec, key, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteIndependentValue(valueCodec, value, output, sessionPool); written++; } @@ -97,13 +96,13 @@ private void Apply(ref Reader reader, IDurableDictionaryCommandH { case SetCommand: { - var key = OrleansBinaryCommandCodecHelpers.ReadValue(keyCodec, ref reader); - var value = OrleansBinaryCommandCodecHelpers.ReadValue(valueCodec, ref reader); + var key = OrleansBinaryCommandCodecHelpers.ReadIndependentValue(keyCodec, ref reader); + var value = OrleansBinaryCommandCodecHelpers.ReadIndependentValue(valueCodec, ref reader); consumer.ApplySet(key, value); break; } case RemoveCommand: - consumer.ApplyRemove(OrleansBinaryCommandCodecHelpers.ReadValue(keyCodec, ref reader)); + consumer.ApplyRemove(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(keyCodec, ref reader)); break; case ClearCommand: consumer.ApplyClear(); diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableListCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableListCommandCodec.cs index a68d48d0c44..6cb0c60145e 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableListCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableListCommandCodec.cs @@ -26,7 +26,7 @@ public void WriteAdd(T item, JournalStreamWriter writer) var payloadWriter = Writer.Create(output, session: null!); payloadWriter.WriteVarUInt32(AddCommand); payloadWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteValue(codec, item, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, item, output, sessionPool); entry.Commit(); } @@ -39,7 +39,7 @@ public void WriteSet(int index, T item, JournalStreamWriter writer) payloadWriter.WriteVarUInt32(SetCommand); payloadWriter.WriteVarUInt32((uint)index); payloadWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteValue(codec, item, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, item, output, sessionPool); entry.Commit(); } @@ -52,7 +52,7 @@ public void WriteInsert(int index, T item, JournalStreamWriter writer) payloadWriter.WriteVarUInt32(InsertCommand); payloadWriter.WriteVarUInt32((uint)index); payloadWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteValue(codec, item, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, item, output, sessionPool); entry.Commit(); } @@ -91,7 +91,7 @@ public void WriteSnapshot(IReadOnlyCollection items, JournalStreamWriter writ foreach (var item in items) { CollectionCodecHelpers.ThrowIfSnapshotItemCountExceeded(count, written); - OrleansBinaryCommandCodecHelpers.WriteValue(codec, item, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, item, output, sessionPool); written++; } @@ -119,19 +119,19 @@ private void Apply(ref Reader reader, IDurableListCommandHandler switch (command) { case AddCommand: - consumer.ApplyAdd(OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader)); + consumer.ApplyAdd(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader)); break; case SetCommand: { var index = OrleansBinaryCollectionWireHelpers.ReadListIndex(ref reader); - var item = OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader); + var item = OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader); consumer.ApplySet(index, item); break; } case InsertCommand: { var index = OrleansBinaryCollectionWireHelpers.ReadListIndex(ref reader); - var item = OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader); + var item = OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader); consumer.ApplyInsert(index, item); break; } diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableQueueCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableQueueCommandCodec.cs index e9882426068..da980b8c23a 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableQueueCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableQueueCommandCodec.cs @@ -24,7 +24,7 @@ public void WriteEnqueue(T item, JournalStreamWriter writer) var payloadWriter = Writer.Create(output, session: null!); payloadWriter.WriteVarUInt32(EnqueueCommand); payloadWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteValue(codec, item, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, item, output, sessionPool); entry.Commit(); } @@ -62,7 +62,7 @@ public void WriteSnapshot(IReadOnlyCollection items, JournalStreamWriter writ foreach (var item in items) { CollectionCodecHelpers.ThrowIfSnapshotItemCountExceeded(count, written); - OrleansBinaryCommandCodecHelpers.WriteValue(codec, item, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, item, output, sessionPool); written++; } @@ -90,7 +90,7 @@ private void Apply(ref Reader reader, IDurableQueueCommandHandle switch (command) { case EnqueueCommand: - consumer.ApplyEnqueue(OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader)); + consumer.ApplyEnqueue(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader)); break; case DequeueCommand: consumer.ApplyDequeue(); diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableSetCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableSetCommandCodec.cs index a938b18fb58..59f6144f86d 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableSetCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableSetCommandCodec.cs @@ -24,7 +24,7 @@ public void WriteAdd(T item, JournalStreamWriter writer) var payloadWriter = Writer.Create(output, session: null!); payloadWriter.WriteVarUInt32(AddCommand); payloadWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteValue(codec, item, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, item, output, sessionPool); entry.Commit(); } @@ -36,7 +36,7 @@ public void WriteRemove(T item, JournalStreamWriter writer) var payloadWriter = Writer.Create(output, session: null!); payloadWriter.WriteVarUInt32(RemoveCommand); payloadWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteValue(codec, item, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, item, output, sessionPool); entry.Commit(); } @@ -64,7 +64,7 @@ public void WriteSnapshot(IReadOnlyCollection items, JournalStreamWriter writ foreach (var item in items) { CollectionCodecHelpers.ThrowIfSnapshotItemCountExceeded(count, written); - OrleansBinaryCommandCodecHelpers.WriteValue(codec, item, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, item, output, sessionPool); written++; } @@ -92,10 +92,10 @@ private void Apply(ref Reader reader, IDurableSetCommandHandler< switch (command) { case AddCommand: - consumer.ApplyAdd(OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader)); + consumer.ApplyAdd(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader)); break; case RemoveCommand: - consumer.ApplyRemove(OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader)); + consumer.ApplyRemove(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader)); break; case ClearCommand: consumer.ApplyClear(); diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableTaskCompletionSourceCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableTaskCompletionSourceCommandCodec.cs index aae0490e3cc..d7fade5b296 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableTaskCompletionSourceCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableTaskCompletionSourceCommandCodec.cs @@ -35,7 +35,7 @@ public void WriteCompleted(T value, JournalStreamWriter writer) var span = output.GetSpan(1); span[0] = (byte)DurableTaskCompletionSourceStatus.Completed; output.Advance(1); - OrleansBinaryCommandCodecHelpers.WriteValue(codec, value, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, value, output, sessionPool); entry.Commit(); } @@ -47,7 +47,7 @@ public void WriteFaulted(Exception exception, JournalStreamWriter writer) var span = output.GetSpan(1); span[0] = (byte)DurableTaskCompletionSourceStatus.Faulted; output.Advance(1); - OrleansBinaryCommandCodecHelpers.WriteValue(exceptionCodec, exception, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteIndependentValue(exceptionCodec, exception, output, sessionPool); entry.Commit(); } @@ -90,10 +90,10 @@ private void Apply(ref Reader reader, IDurableTaskCompletionSour consumer.ApplyPending(); break; case DurableTaskCompletionSourceStatus.Completed: - consumer.ApplyCompleted(OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader)); + consumer.ApplyCompleted(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader)); break; case DurableTaskCompletionSourceStatus.Faulted: - consumer.ApplyFaulted(OrleansBinaryCommandCodecHelpers.ReadValue(exceptionCodec, ref reader)); + consumer.ApplyFaulted(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(exceptionCodec, ref reader)); break; case DurableTaskCompletionSourceStatus.Canceled: consumer.ApplyCanceled(); diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableValueCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableValueCommandCodec.cs index 03101bdc838..2e70e00c3bc 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableValueCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableValueCommandCodec.cs @@ -21,7 +21,7 @@ public void WriteSet(T value, JournalStreamWriter writer) var payloadWriter = Writer.Create(output, session: null!); payloadWriter.WriteVarUInt32(SetValueCommand); payloadWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteValue(codec, value, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, value, output, sessionPool); entry.Commit(); } @@ -45,7 +45,7 @@ private void Apply(ref Reader reader, IDurableValueCommandHandle switch (command) { case SetValueCommand: - consumer.ApplySet(OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader)); + consumer.ApplySet(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader)); break; default: throw new NotSupportedException($"Command type {command} is not supported"); diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryPersistentStateCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryPersistentStateCommandCodec.cs index 9f75264da9a..9468150a290 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryPersistentStateCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryPersistentStateCommandCodec.cs @@ -22,7 +22,7 @@ public void WriteSet(T state, ulong version, JournalStreamWriter writer) var headerWriter = Writer.Create(output, session: null!); headerWriter.WriteVarUInt32(SetValueCommand); headerWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteValue(codec, state, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, state, output, sessionPool); var versionWriter = Writer.Create(output, session: null!); versionWriter.WriteVarUInt64(version); versionWriter.Commit(); @@ -59,7 +59,7 @@ private void Apply(ref Reader reader, IPersistentStateCommandHan switch (command) { case SetValueCommand: - var state = OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader); + var state = OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader); var version = reader.ReadVarUInt64(); consumer.ApplySet(state, version); break; diff --git a/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs b/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs index b21fe565c98..89fe6d66992 100644 --- a/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs +++ b/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs @@ -39,7 +39,7 @@ public void DictionaryCodec_AllCommands_RoundTrip() } [Fact] - public void DictionaryCodec_PreChangeSnapshotPayload_ReplaysIndependentReferenceScopes() + public void DictionaryCodec_SnapshotPayload_ReplaysIndependentReferenceScopes() { var codec = new OrleansBinaryDurableDictionaryCommandCodec( ValueCodec(), @@ -58,6 +58,27 @@ public void DictionaryCodec_PreChangeSnapshotPayload_ReplaysIndependentReference AssertAliases(consumer.SnapshotItems.Select(static item => item.Value)); } + [Fact] + public void DictionaryCodec_Set_ReplaysKeyAndValueAsIndependentReferenceScopes() + { + var codec = new OrleansBinaryDurableDictionaryCommandCodec( + ValueCodec(), + ValueCodec(), + SessionPool); + var shared = new byte[] { 1, 2, 3 }; + var key = new SnapshotReferenceRecord { Payload = shared, Alias = shared }; + var value = new SnapshotReferenceRecord { Payload = shared, Alias = shared }; + var payload = CodecTestHelpers.WriteEntry(writer => codec.WriteSet(key, value, writer)); + + var consumer = new RecordingDictionaryCommandHandler(); + codec.Apply(CodecTestHelpers.ReadBuffer(payload), consumer); + + var item = Assert.Single(consumer.SnapshotItems); + Assert.Same(item.Key.Payload, item.Key.Alias); + Assert.Same(item.Value.Payload, item.Value.Alias); + Assert.NotSame(item.Key.Payload, item.Value.Payload); + } + [Fact] public void ListCodec_AllCommands_RoundTrip() { @@ -88,7 +109,7 @@ public void ListCodec_AllCommands_RoundTrip() } [Fact] - public void ListCodec_PreChangeSnapshotPayload_ReplaysIndependentReferenceScopes() + public void ListCodec_SnapshotPayload_ReplaysIndependentReferenceScopes() { var codec = new OrleansBinaryDurableListCommandCodec( ValueCodec(), @@ -128,7 +149,7 @@ public void QueueCodec_AllCommands_RoundTrip() } [Fact] - public void QueueCodec_PreChangeSnapshotPayload_ReplaysIndependentReferenceScopes() + public void QueueCodec_SnapshotPayload_ReplaysIndependentReferenceScopes() { var codec = new OrleansBinaryDurableQueueCommandCodec( ValueCodec(), @@ -168,7 +189,7 @@ public void SetCodec_AllCommands_RoundTrip() } [Fact] - public void SetCodec_PreChangeSnapshotPayload_ReplaysIndependentReferenceScopes() + public void SetCodec_SnapshotPayload_ReplaysIndependentReferenceScopes() { var codec = new OrleansBinaryDurableSetCommandCodec( ValueCodec(), From cafbe8f041597289a78b3b79d799de5091ae7ff2 Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Mon, 24 Aug 2026 11:29:31 -0700 Subject: [PATCH 3/7] refactor(journaling): simplify codec helper names Keep per-value serializer-session isolation as the sole helper behavior and use concise WriteValue and ReadValue names. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f32c3454-1184-4a8b-81c3-7a9f9b094617 --- .../OrleansBinaryCommandCodecHelpers.cs | 6 +++--- ...eansBinaryDurableDictionaryCommandCodec.cs | 20 +++++++++---------- .../OrleansBinaryDurableListCommandCodec.cs | 16 +++++++-------- .../OrleansBinaryDurableQueueCommandCodec.cs | 8 ++++---- .../OrleansBinaryDurableSetCommandCodec.cs | 12 +++++------ ...DurableTaskCompletionSourceCommandCodec.cs | 8 ++++---- .../OrleansBinaryDurableValueCommandCodec.cs | 4 ++-- ...rleansBinaryPersistentStateCommandCodec.cs | 4 ++-- 8 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryCommandCodecHelpers.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryCommandCodecHelpers.cs index 36026ca07e3..5b1e4757fe5 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryCommandCodecHelpers.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryCommandCodecHelpers.cs @@ -6,11 +6,11 @@ namespace Orleans.Journaling; /// -/// Helpers shared by the Orleans binary durable command codecs. +/// Reads and writes Orleans binary command values using an isolated serializer session for each value. /// internal static class OrleansBinaryCommandCodecHelpers { - public static void WriteIndependentValue( + public static void WriteValue( IFieldCodec codec, T value, IBufferWriter output, @@ -22,7 +22,7 @@ public static void WriteIndependentValue( writer.Commit(); } - public static T ReadIndependentValue(IFieldCodec codec, ref Reader reader) + public static T ReadValue(IFieldCodec codec, ref Reader reader) { reader.Session.Reset(); try diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs index ec63b8659b1..32d103dd159 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs @@ -25,8 +25,8 @@ public void WriteSet(TKey key, TValue value, JournalStreamWriter writer) var payloadWriter = Writer.Create(output, session: null!); payloadWriter.WriteVarUInt32(SetCommand); payloadWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteIndependentValue(keyCodec, key, output, sessionPool); - OrleansBinaryCommandCodecHelpers.WriteIndependentValue(valueCodec, value, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteValue(keyCodec, key, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteValue(valueCodec, value, output, sessionPool); entry.Commit(); } @@ -38,7 +38,7 @@ public void WriteRemove(TKey key, JournalStreamWriter writer) var payloadWriter = Writer.Create(output, session: null!); payloadWriter.WriteVarUInt32(RemoveCommand); payloadWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteIndependentValue(keyCodec, key, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteValue(keyCodec, key, output, sessionPool); entry.Commit(); } @@ -66,8 +66,8 @@ public void WriteSnapshot(IReadOnlyCollection> items, foreach (var (key, value) in items) { CollectionCodecHelpers.ThrowIfSnapshotItemCountExceeded(count, written); - OrleansBinaryCommandCodecHelpers.WriteIndependentValue(keyCodec, key, output, sessionPool); - OrleansBinaryCommandCodecHelpers.WriteIndependentValue(valueCodec, value, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteValue(keyCodec, key, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteValue(valueCodec, value, output, sessionPool); written++; } @@ -96,13 +96,13 @@ private void Apply(ref Reader reader, IDurableDictionaryCommandH { case SetCommand: { - var key = OrleansBinaryCommandCodecHelpers.ReadIndependentValue(keyCodec, ref reader); - var value = OrleansBinaryCommandCodecHelpers.ReadIndependentValue(valueCodec, ref reader); + var key = OrleansBinaryCommandCodecHelpers.ReadValue(keyCodec, ref reader); + var value = OrleansBinaryCommandCodecHelpers.ReadValue(valueCodec, ref reader); consumer.ApplySet(key, value); break; } case RemoveCommand: - consumer.ApplyRemove(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(keyCodec, ref reader)); + consumer.ApplyRemove(OrleansBinaryCommandCodecHelpers.ReadValue(keyCodec, ref reader)); break; case ClearCommand: consumer.ApplyClear(); @@ -122,8 +122,8 @@ private void ApplySnapshot(ref Reader reader, IDurableDictionary consumer.Reset(count); for (var i = 0; i < count; i++) { - var key = OrleansBinaryCommandCodecHelpers.ReadIndependentValue(keyCodec, ref reader); - var value = OrleansBinaryCommandCodecHelpers.ReadIndependentValue(valueCodec, ref reader); + var key = OrleansBinaryCommandCodecHelpers.ReadValue(keyCodec, ref reader); + var value = OrleansBinaryCommandCodecHelpers.ReadValue(valueCodec, ref reader); consumer.ApplySet(key, value); } } diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableListCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableListCommandCodec.cs index 6cb0c60145e..ba38edf008a 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableListCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableListCommandCodec.cs @@ -26,7 +26,7 @@ public void WriteAdd(T item, JournalStreamWriter writer) var payloadWriter = Writer.Create(output, session: null!); payloadWriter.WriteVarUInt32(AddCommand); payloadWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, item, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteValue(codec, item, output, sessionPool); entry.Commit(); } @@ -39,7 +39,7 @@ public void WriteSet(int index, T item, JournalStreamWriter writer) payloadWriter.WriteVarUInt32(SetCommand); payloadWriter.WriteVarUInt32((uint)index); payloadWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, item, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteValue(codec, item, output, sessionPool); entry.Commit(); } @@ -52,7 +52,7 @@ public void WriteInsert(int index, T item, JournalStreamWriter writer) payloadWriter.WriteVarUInt32(InsertCommand); payloadWriter.WriteVarUInt32((uint)index); payloadWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, item, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteValue(codec, item, output, sessionPool); entry.Commit(); } @@ -91,7 +91,7 @@ public void WriteSnapshot(IReadOnlyCollection items, JournalStreamWriter writ foreach (var item in items) { CollectionCodecHelpers.ThrowIfSnapshotItemCountExceeded(count, written); - OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, item, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteValue(codec, item, output, sessionPool); written++; } @@ -119,19 +119,19 @@ private void Apply(ref Reader reader, IDurableListCommandHandler switch (command) { case AddCommand: - consumer.ApplyAdd(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader)); + consumer.ApplyAdd(OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader)); break; case SetCommand: { var index = OrleansBinaryCollectionWireHelpers.ReadListIndex(ref reader); - var item = OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader); + var item = OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader); consumer.ApplySet(index, item); break; } case InsertCommand: { var index = OrleansBinaryCollectionWireHelpers.ReadListIndex(ref reader); - var item = OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader); + var item = OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader); consumer.ApplyInsert(index, item); break; } @@ -156,7 +156,7 @@ private void ApplySnapshot(ref Reader reader, IDurableListComman consumer.Reset(count); for (var i = 0; i < count; i++) { - consumer.ApplyAdd(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader)); + consumer.ApplyAdd(OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader)); } } diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableQueueCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableQueueCommandCodec.cs index da980b8c23a..2ab6b34fcfb 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableQueueCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableQueueCommandCodec.cs @@ -24,7 +24,7 @@ public void WriteEnqueue(T item, JournalStreamWriter writer) var payloadWriter = Writer.Create(output, session: null!); payloadWriter.WriteVarUInt32(EnqueueCommand); payloadWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, item, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteValue(codec, item, output, sessionPool); entry.Commit(); } @@ -62,7 +62,7 @@ public void WriteSnapshot(IReadOnlyCollection items, JournalStreamWriter writ foreach (var item in items) { CollectionCodecHelpers.ThrowIfSnapshotItemCountExceeded(count, written); - OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, item, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteValue(codec, item, output, sessionPool); written++; } @@ -90,7 +90,7 @@ private void Apply(ref Reader reader, IDurableQueueCommandHandle switch (command) { case EnqueueCommand: - consumer.ApplyEnqueue(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader)); + consumer.ApplyEnqueue(OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader)); break; case DequeueCommand: consumer.ApplyDequeue(); @@ -113,7 +113,7 @@ private void ApplySnapshot(ref Reader reader, IDurableQueueComma consumer.Reset(count); for (var i = 0; i < count; i++) { - consumer.ApplyEnqueue(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader)); + consumer.ApplyEnqueue(OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader)); } } diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableSetCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableSetCommandCodec.cs index 59f6144f86d..8b8585b13a3 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableSetCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableSetCommandCodec.cs @@ -24,7 +24,7 @@ public void WriteAdd(T item, JournalStreamWriter writer) var payloadWriter = Writer.Create(output, session: null!); payloadWriter.WriteVarUInt32(AddCommand); payloadWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, item, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteValue(codec, item, output, sessionPool); entry.Commit(); } @@ -36,7 +36,7 @@ public void WriteRemove(T item, JournalStreamWriter writer) var payloadWriter = Writer.Create(output, session: null!); payloadWriter.WriteVarUInt32(RemoveCommand); payloadWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, item, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteValue(codec, item, output, sessionPool); entry.Commit(); } @@ -64,7 +64,7 @@ public void WriteSnapshot(IReadOnlyCollection items, JournalStreamWriter writ foreach (var item in items) { CollectionCodecHelpers.ThrowIfSnapshotItemCountExceeded(count, written); - OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, item, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteValue(codec, item, output, sessionPool); written++; } @@ -92,10 +92,10 @@ private void Apply(ref Reader reader, IDurableSetCommandHandler< switch (command) { case AddCommand: - consumer.ApplyAdd(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader)); + consumer.ApplyAdd(OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader)); break; case RemoveCommand: - consumer.ApplyRemove(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader)); + consumer.ApplyRemove(OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader)); break; case ClearCommand: consumer.ApplyClear(); @@ -115,7 +115,7 @@ private void ApplySnapshot(ref Reader reader, IDurableSetCommand consumer.Reset(count); for (var i = 0; i < count; i++) { - consumer.ApplyAdd(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader)); + consumer.ApplyAdd(OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader)); } } } diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableTaskCompletionSourceCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableTaskCompletionSourceCommandCodec.cs index d7fade5b296..aae0490e3cc 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableTaskCompletionSourceCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableTaskCompletionSourceCommandCodec.cs @@ -35,7 +35,7 @@ public void WriteCompleted(T value, JournalStreamWriter writer) var span = output.GetSpan(1); span[0] = (byte)DurableTaskCompletionSourceStatus.Completed; output.Advance(1); - OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, value, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteValue(codec, value, output, sessionPool); entry.Commit(); } @@ -47,7 +47,7 @@ public void WriteFaulted(Exception exception, JournalStreamWriter writer) var span = output.GetSpan(1); span[0] = (byte)DurableTaskCompletionSourceStatus.Faulted; output.Advance(1); - OrleansBinaryCommandCodecHelpers.WriteIndependentValue(exceptionCodec, exception, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteValue(exceptionCodec, exception, output, sessionPool); entry.Commit(); } @@ -90,10 +90,10 @@ private void Apply(ref Reader reader, IDurableTaskCompletionSour consumer.ApplyPending(); break; case DurableTaskCompletionSourceStatus.Completed: - consumer.ApplyCompleted(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader)); + consumer.ApplyCompleted(OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader)); break; case DurableTaskCompletionSourceStatus.Faulted: - consumer.ApplyFaulted(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(exceptionCodec, ref reader)); + consumer.ApplyFaulted(OrleansBinaryCommandCodecHelpers.ReadValue(exceptionCodec, ref reader)); break; case DurableTaskCompletionSourceStatus.Canceled: consumer.ApplyCanceled(); diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableValueCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableValueCommandCodec.cs index 2e70e00c3bc..03101bdc838 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableValueCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableValueCommandCodec.cs @@ -21,7 +21,7 @@ public void WriteSet(T value, JournalStreamWriter writer) var payloadWriter = Writer.Create(output, session: null!); payloadWriter.WriteVarUInt32(SetValueCommand); payloadWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, value, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteValue(codec, value, output, sessionPool); entry.Commit(); } @@ -45,7 +45,7 @@ private void Apply(ref Reader reader, IDurableValueCommandHandle switch (command) { case SetValueCommand: - consumer.ApplySet(OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader)); + consumer.ApplySet(OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader)); break; default: throw new NotSupportedException($"Command type {command} is not supported"); diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryPersistentStateCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryPersistentStateCommandCodec.cs index 9468150a290..9f75264da9a 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryPersistentStateCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryPersistentStateCommandCodec.cs @@ -22,7 +22,7 @@ public void WriteSet(T state, ulong version, JournalStreamWriter writer) var headerWriter = Writer.Create(output, session: null!); headerWriter.WriteVarUInt32(SetValueCommand); headerWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteIndependentValue(codec, state, output, sessionPool); + OrleansBinaryCommandCodecHelpers.WriteValue(codec, state, output, sessionPool); var versionWriter = Writer.Create(output, session: null!); versionWriter.WriteVarUInt64(version); versionWriter.Commit(); @@ -59,7 +59,7 @@ private void Apply(ref Reader reader, IPersistentStateCommandHan switch (command) { case SetValueCommand: - var state = OrleansBinaryCommandCodecHelpers.ReadIndependentValue(codec, ref reader); + var state = OrleansBinaryCommandCodecHelpers.ReadValue(codec, ref reader); var version = reader.ReadVarUInt64(); consumer.ApplySet(state, version); break; From 92508f2d3166d874dec2f9796bda7e7455c7a41c Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Mon, 24 Aug 2026 11:36:23 -0700 Subject: [PATCH 4/7] fix(journaling): preserve legacy dictionary set replay --- ...eansBinaryDurableDictionaryCommandCodec.cs | 16 ++++++++- .../OrleansBinaryCommandCodecTests.cs | 33 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs index 32d103dd159..18142591ec0 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs @@ -12,10 +12,11 @@ internal sealed class OrleansBinaryDurableDictionaryCommandCodec( IFieldCodec valueCodec, SerializerSessionPool sessionPool) : IDurableDictionaryCommandCodec where TKey : notnull { - private const uint SetCommand = 0; + private const uint LegacySetCommand = 0; private const uint RemoveCommand = 1; private const uint ClearCommand = 2; private const uint SnapshotCommand = 3; + private const uint SetCommand = 4; /// public void WriteSet(TKey key, TValue value, JournalStreamWriter writer) @@ -94,6 +95,13 @@ private void Apply(ref Reader reader, IDurableDictionaryCommandH var command = reader.ReadVarUInt32(); switch (command) { + case LegacySetCommand: + { + var key = ReadSharedValue(keyCodec, ref reader); + var value = ReadSharedValue(valueCodec, ref reader); + consumer.ApplySet(key, value); + break; + } case SetCommand: { var key = OrleansBinaryCommandCodecHelpers.ReadValue(keyCodec, ref reader); @@ -115,6 +123,12 @@ private void Apply(ref Reader reader, IDurableDictionaryCommandH } } + private static TField ReadSharedValue(IFieldCodec codec, ref Reader reader) + { + var field = reader.ReadFieldHeader(); + return codec.ReadValue(ref reader, field)!; + } + private void ApplySnapshot(ref Reader reader, IDurableDictionaryCommandHandler consumer) { var count = OrleansBinaryCollectionWireHelpers.ReadSnapshotCount(ref reader); diff --git a/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs b/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs index 89fe6d66992..3025ae46c06 100644 --- a/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs +++ b/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs @@ -79,6 +79,39 @@ public void DictionaryCodec_Set_ReplaysKeyAndValueAsIndependentReferenceScopes() Assert.NotSame(item.Key.Payload, item.Value.Payload); } + [Fact] + public void DictionaryCodec_Set_ReplaysLegacySharedReferenceScope() + { + var keyCodec = ValueCodec(); + var valueCodec = ValueCodec(); + var codec = new OrleansBinaryDurableDictionaryCommandCodec( + keyCodec, + valueCodec, + SessionPool); + var shared = new byte[] { 1, 2, 3 }; + var key = new SnapshotReferenceRecord { Payload = shared, Alias = shared }; + var value = new SnapshotReferenceRecord { Payload = shared, Alias = shared }; + var payload = CodecTestHelpers.WriteEntry(writer => + { + using var entry = writer.BeginEntry(); + using var session = SessionPool.GetSession(); + var payloadWriter = Writer.Create(entry.Writer, session); + payloadWriter.WriteVarUInt32(0); + keyCodec.WriteField(ref payloadWriter, 0, typeof(SnapshotReferenceRecord), key); + valueCodec.WriteField(ref payloadWriter, 1, typeof(SnapshotReferenceRecord), value); + payloadWriter.Commit(); + entry.Commit(); + }); + + var consumer = new RecordingDictionaryCommandHandler(); + codec.Apply(CodecTestHelpers.ReadBuffer(payload), consumer); + + var item = Assert.Single(consumer.SnapshotItems); + Assert.Same(item.Key.Payload, item.Key.Alias); + Assert.Same(item.Key.Payload, item.Value.Payload); + Assert.Same(item.Value.Payload, item.Value.Alias); + } + [Fact] public void ListCodec_AllCommands_RoundTrip() { From 4ac1a7991f5047f2b5766586403700b3690ec6fc Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Mon, 24 Aug 2026 11:46:14 -0700 Subject: [PATCH 5/7] fix(journaling): scope dictionary references per entry Share serializer references between each dictionary key and value while resetting the session between commands and snapshot entries. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f32c3454-1184-4a8b-81c3-7a9f9b094617 --- ...eansBinaryDurableDictionaryCommandCodec.cs | 38 +++++++++++---- .../OrleansBinaryCommandCodecTests.cs | 48 +++++++++++++++++-- 2 files changed, 74 insertions(+), 12 deletions(-) diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs index 18142591ec0..a7477fc56a9 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs @@ -1,3 +1,4 @@ +using System.Buffers; using Orleans.Serialization.Buffers; using Orleans.Serialization.Codecs; using Orleans.Serialization.Session; @@ -26,8 +27,7 @@ public void WriteSet(TKey key, TValue value, JournalStreamWriter writer) var payloadWriter = Writer.Create(output, session: null!); payloadWriter.WriteVarUInt32(SetCommand); payloadWriter.Commit(); - OrleansBinaryCommandCodecHelpers.WriteValue(keyCodec, key, output, sessionPool); - OrleansBinaryCommandCodecHelpers.WriteValue(valueCodec, value, output, sessionPool); + WriteKeyValue(key, value, output); entry.Commit(); } @@ -67,8 +67,7 @@ public void WriteSnapshot(IReadOnlyCollection> items, foreach (var (key, value) in items) { CollectionCodecHelpers.ThrowIfSnapshotItemCountExceeded(count, written); - OrleansBinaryCommandCodecHelpers.WriteValue(keyCodec, key, output, sessionPool); - OrleansBinaryCommandCodecHelpers.WriteValue(valueCodec, value, output, sessionPool); + WriteKeyValue(key, value, output); written++; } @@ -104,8 +103,7 @@ private void Apply(ref Reader reader, IDurableDictionaryCommandH } case SetCommand: { - var key = OrleansBinaryCommandCodecHelpers.ReadValue(keyCodec, ref reader); - var value = OrleansBinaryCommandCodecHelpers.ReadValue(valueCodec, ref reader); + var (key, value) = ReadKeyValue(ref reader); consumer.ApplySet(key, value); break; } @@ -136,10 +134,34 @@ private void ApplySnapshot(ref Reader reader, IDurableDictionary consumer.Reset(count); for (var i = 0; i < count; i++) { - var key = OrleansBinaryCommandCodecHelpers.ReadValue(keyCodec, ref reader); - var value = OrleansBinaryCommandCodecHelpers.ReadValue(valueCodec, ref reader); + var (key, value) = ReadKeyValue(ref reader); consumer.ApplySet(key, value); } } + private void WriteKeyValue(TKey key, TValue value, IBufferWriter output) + { + using var session = sessionPool.GetSession(); + var writer = Writer.Create(output, session); + keyCodec.WriteField(ref writer, 0, typeof(TKey), key); + valueCodec.WriteField(ref writer, 1, typeof(TValue), value); + writer.Commit(); + } + + private (TKey Key, TValue Value) ReadKeyValue(ref Reader reader) + { + reader.Session.Reset(); + try + { + var keyField = reader.ReadFieldHeader(); + var key = keyCodec.ReadValue(ref reader, keyField)!; + var valueField = reader.ReadFieldHeader(); + var value = valueCodec.ReadValue(ref reader, valueField)!; + return (key, value); + } + finally + { + reader.Session.Reset(); + } + } } diff --git a/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs b/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs index 3025ae46c06..d5197ffdfa1 100644 --- a/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs +++ b/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs @@ -39,7 +39,7 @@ public void DictionaryCodec_AllCommands_RoundTrip() } [Fact] - public void DictionaryCodec_SnapshotPayload_ReplaysIndependentReferenceScopes() + public void DictionaryCodec_SnapshotPayload_ReplaysEntryReferenceScopes() { var codec = new OrleansBinaryDurableDictionaryCommandCodec( ValueCodec(), @@ -50,7 +50,7 @@ public void DictionaryCodec_SnapshotPayload_ReplaysIndependentReferenceScopes() writer => codec.WriteSnapshot([new("first", items[0]), new("second", items[1])], writer)); Assert.Equal( - "0705400B6669727374204007010203C105E0400D7365636F6E64204007040506C105E0", + "0705400B6669727374214007010203C107E0400D7365636F6E64214007040506C107E0", Convert.ToHexString(payload)); var consumer = new RecordingDictionaryCommandHandler(); @@ -59,7 +59,7 @@ public void DictionaryCodec_SnapshotPayload_ReplaysIndependentReferenceScopes() } [Fact] - public void DictionaryCodec_Set_ReplaysKeyAndValueAsIndependentReferenceScopes() + public void DictionaryCodec_Set_PreservesReferencesBetweenKeyAndValue() { var codec = new OrleansBinaryDurableDictionaryCommandCodec( ValueCodec(), @@ -76,7 +76,47 @@ public void DictionaryCodec_Set_ReplaysKeyAndValueAsIndependentReferenceScopes() var item = Assert.Single(consumer.SnapshotItems); Assert.Same(item.Key.Payload, item.Key.Alias); Assert.Same(item.Value.Payload, item.Value.Alias); - Assert.NotSame(item.Key.Payload, item.Value.Payload); + Assert.Same(item.Key.Payload, item.Value.Payload); + } + + [Fact] + public void DictionaryCodec_Snapshot_PreservesEntryReferencesAndIsolatesEntries() + { + var codec = new OrleansBinaryDurableDictionaryCommandCodec( + ValueCodec(), + ValueCodec(), + SessionPool); + var shared = new byte[] { 1, 2, 3 }; + var payload = CodecTestHelpers.WriteEntry( + writer => codec.WriteSnapshot( + [ + new( + new() { Payload = shared, Alias = shared }, + new() { Payload = shared, Alias = shared }), + new( + new() { Payload = shared, Alias = shared }, + new() { Payload = shared, Alias = shared }) + ], + writer)); + + var consumer = new RecordingDictionaryCommandHandler(); + codec.Apply(CodecTestHelpers.ReadBuffer(payload), consumer); + + Assert.Collection( + consumer.SnapshotItems, + first => + { + Assert.Same(first.Key.Payload, first.Key.Alias); + Assert.Same(first.Value.Payload, first.Value.Alias); + Assert.Same(first.Key.Payload, first.Value.Payload); + }, + second => + { + Assert.Same(second.Key.Payload, second.Key.Alias); + Assert.Same(second.Value.Payload, second.Value.Alias); + Assert.Same(second.Key.Payload, second.Value.Payload); + Assert.NotSame(consumer.SnapshotItems[0].Key.Payload, second.Key.Payload); + }); } [Fact] From ef1d85fc5c0d529221786f183ea824032de5e2a6 Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Mon, 24 Aug 2026 11:50:09 -0700 Subject: [PATCH 6/7] refactor(journaling): remove unshipped set compatibility Keep command zero as the single dictionary set format and rely on entry-level serializer scopes for both commands and snapshots. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f32c3454-1184-4a8b-81c3-7a9f9b094617 --- ...eansBinaryDurableDictionaryCommandCodec.cs | 16 +-------- .../OrleansBinaryCommandCodecTests.cs | 33 ------------------- 2 files changed, 1 insertion(+), 48 deletions(-) diff --git a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs index a7477fc56a9..0b78d6ed78d 100644 --- a/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs +++ b/src/Orleans.Journaling/Formats/OrleansBinary/OrleansBinaryDurableDictionaryCommandCodec.cs @@ -13,11 +13,10 @@ internal sealed class OrleansBinaryDurableDictionaryCommandCodec( IFieldCodec valueCodec, SerializerSessionPool sessionPool) : IDurableDictionaryCommandCodec where TKey : notnull { - private const uint LegacySetCommand = 0; + private const uint SetCommand = 0; private const uint RemoveCommand = 1; private const uint ClearCommand = 2; private const uint SnapshotCommand = 3; - private const uint SetCommand = 4; /// public void WriteSet(TKey key, TValue value, JournalStreamWriter writer) @@ -94,13 +93,6 @@ private void Apply(ref Reader reader, IDurableDictionaryCommandH var command = reader.ReadVarUInt32(); switch (command) { - case LegacySetCommand: - { - var key = ReadSharedValue(keyCodec, ref reader); - var value = ReadSharedValue(valueCodec, ref reader); - consumer.ApplySet(key, value); - break; - } case SetCommand: { var (key, value) = ReadKeyValue(ref reader); @@ -121,12 +113,6 @@ private void Apply(ref Reader reader, IDurableDictionaryCommandH } } - private static TField ReadSharedValue(IFieldCodec codec, ref Reader reader) - { - var field = reader.ReadFieldHeader(); - return codec.ReadValue(ref reader, field)!; - } - private void ApplySnapshot(ref Reader reader, IDurableDictionaryCommandHandler consumer) { var count = OrleansBinaryCollectionWireHelpers.ReadSnapshotCount(ref reader); diff --git a/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs b/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs index d5197ffdfa1..4623248fcfc 100644 --- a/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs +++ b/test/Orleans.Journaling.Tests/OrleansBinaryCommandCodecTests.cs @@ -119,39 +119,6 @@ public void DictionaryCodec_Snapshot_PreservesEntryReferencesAndIsolatesEntries( }); } - [Fact] - public void DictionaryCodec_Set_ReplaysLegacySharedReferenceScope() - { - var keyCodec = ValueCodec(); - var valueCodec = ValueCodec(); - var codec = new OrleansBinaryDurableDictionaryCommandCodec( - keyCodec, - valueCodec, - SessionPool); - var shared = new byte[] { 1, 2, 3 }; - var key = new SnapshotReferenceRecord { Payload = shared, Alias = shared }; - var value = new SnapshotReferenceRecord { Payload = shared, Alias = shared }; - var payload = CodecTestHelpers.WriteEntry(writer => - { - using var entry = writer.BeginEntry(); - using var session = SessionPool.GetSession(); - var payloadWriter = Writer.Create(entry.Writer, session); - payloadWriter.WriteVarUInt32(0); - keyCodec.WriteField(ref payloadWriter, 0, typeof(SnapshotReferenceRecord), key); - valueCodec.WriteField(ref payloadWriter, 1, typeof(SnapshotReferenceRecord), value); - payloadWriter.Commit(); - entry.Commit(); - }); - - var consumer = new RecordingDictionaryCommandHandler(); - codec.Apply(CodecTestHelpers.ReadBuffer(payload), consumer); - - var item = Assert.Single(consumer.SnapshotItems); - Assert.Same(item.Key.Payload, item.Key.Alias); - Assert.Same(item.Key.Payload, item.Value.Payload); - Assert.Same(item.Value.Payload, item.Value.Alias); - } - [Fact] public void ListCodec_AllCommands_RoundTrip() { From 81add0b17b1a45c158a8287d3982fe714598e9ef Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Mon, 24 Aug 2026 12:43:18 -0700 Subject: [PATCH 7/7] test(journaling): update dictionary wire snapshots Approve the entry-scoped dictionary payloads used by the existing OrleansBinary Verify tests. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f32c3454-1184-4a8b-81c3-7a9f9b094617 --- ...napshotTests.Dictionary_Snapshot_Primitives.verified.txt | 6 +++--- ...decSnapshotTests.Dictionary_Snapshot_Record.verified.txt | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/Orleans.Journaling.Tests/snapshots/OrleansBinaryCodecSnapshotTests.Dictionary_Snapshot_Primitives.verified.txt b/test/Orleans.Journaling.Tests/snapshots/OrleansBinaryCodecSnapshotTests.Dictionary_Snapshot_Primitives.verified.txt index fc4ab392858..85033a3abfa 100644 --- a/test/Orleans.Journaling.Tests/snapshots/OrleansBinaryCodecSnapshotTests.Dictionary_Snapshot_Primitives.verified.txt +++ b/test/Orleans.Journaling.Tests/snapshots/OrleansBinaryCodecSnapshotTests.Dictionary_Snapshot_Primitives.verified.txt @@ -1,5 +1,5 @@ -HEX: 0117000000080000000705400B616C70686100054009626574610009 +HEX: 0117000000080000000705400B616C70686101054009626574610109 DISASSEMBLY: [entry 0] frame-version=1 length=23 streamId=8 payload-bytes=19 -0000 07 05 40 0B 61 6C 70 68 61 00 05 40 09 62 65 74 |..@.alpha..@.bet| -0010 61 00 09 |a..| +0000 07 05 40 0B 61 6C 70 68 61 01 05 40 09 62 65 74 |..@.alpha..@.bet| +0010 61 01 09 |a..| diff --git a/test/Orleans.Journaling.Tests/snapshots/OrleansBinaryCodecSnapshotTests.Dictionary_Snapshot_Record.verified.txt b/test/Orleans.Journaling.Tests/snapshots/OrleansBinaryCodecSnapshotTests.Dictionary_Snapshot_Record.verified.txt index 2bd1c7b61de..3d45b787db5 100644 --- a/test/Orleans.Journaling.Tests/snapshots/OrleansBinaryCodecSnapshotTests.Dictionary_Snapshot_Record.verified.txt +++ b/test/Orleans.Journaling.Tests/snapshots/OrleansBinaryCodecSnapshotTests.Dictionary_Snapshot_Record.verified.txt @@ -1,8 +1,8 @@ -HEX: 0153000000080000000705400B616C70686120E8401F736E617073686F742D7265636F7264011D21E84007746167011A03E0E040096265746120E84015616C742D7265636F7264013521E8400F616C742D7461670145E0E0 +HEX: 0153000000080000000705400B616C70686121E8401F736E617073686F742D7265636F7264011D21E84007746167011A03E0E040096265746121E84015616C742D7265636F7264013521E8400F616C742D7461670145E0E0 DISASSEMBLY: [entry 0] frame-version=1 length=83 streamId=8 payload-bytes=79 -0000 07 05 40 0B 61 6C 70 68 61 20 E8 40 1F 73 6E 61 |..@.alpha .@.sna| +0000 07 05 40 0B 61 6C 70 68 61 21 E8 40 1F 73 6E 61 |..@.alpha!.@.sna| 0010 70 73 68 6F 74 2D 72 65 63 6F 72 64 01 1D 21 E8 |pshot-record..!.| 0020 40 07 74 61 67 01 1A 03 E0 E0 40 09 62 65 74 61 |@.tag.....@.beta| -0030 20 E8 40 15 61 6C 74 2D 72 65 63 6F 72 64 01 35 | .@.alt-record.5| +0030 21 E8 40 15 61 6C 74 2D 72 65 63 6F 72 64 01 35 |!.@.alt-record.5| 0040 21 E8 40 0F 61 6C 74 2D 74 61 67 01 45 E0 E0 |!.@.alt-tag.E..|