diff --git a/src/Wolverine/Envelope.cs b/src/Wolverine/Envelope.cs
index c81e70804..ed575d5ef 100644
--- a/src/Wolverine/Envelope.cs
+++ b/src/Wolverine/Envelope.cs
@@ -292,34 +292,10 @@ public void SetMessageType(Type messageType)
///
public string? TenantId { get; set; }
- private string?[] _acceptedContentTypes = ["application/json"];
- private string? _acceptedContentTypesJoined;
-
///
/// Specifies the accepted content types for the requested reply
///
- public string?[] AcceptedContentTypes
- {
- get => _acceptedContentTypes;
- set
- {
- _acceptedContentTypes = value;
- _acceptedContentTypesJoined = null; // Invalidate cache
- }
- }
-
- ///
- /// Returns the AcceptedContentTypes as a comma-separated string.
- /// This value is cached to avoid repeated allocations during serialization.
- ///
- internal string? AcceptedContentTypesJoined
- {
- get
- {
- if (_acceptedContentTypes.Length == 0) return null;
- return _acceptedContentTypesJoined ??= string.Join(",", _acceptedContentTypes);
- }
- }
+ public string?[] AcceptedContentTypes { get; set; } = ["application/json"];
///
/// Specific message id for this envelope
diff --git a/src/Wolverine/Runtime/Serialization/EnvelopeSerializer.cs b/src/Wolverine/Runtime/Serialization/EnvelopeSerializer.cs
index ca86384cb..c338d9329 100644
--- a/src/Wolverine/Runtime/Serialization/EnvelopeSerializer.cs
+++ b/src/Wolverine/Runtime/Serialization/EnvelopeSerializer.cs
@@ -1,4 +1,3 @@
-using System.Buffers;
using System.Globalization;
using System.Xml;
@@ -6,36 +5,6 @@ namespace Wolverine.Runtime.Serialization;
public static class EnvelopeSerializer
{
- // Initial buffer size - will grow as needed
- private const int InitialBufferSize = 4096;
-
- // Thread-local buffer to avoid repeated rentals in tight loops
- [ThreadStatic]
- private static byte[]? t_buffer;
-
- private static byte[] RentBuffer(int minimumSize)
- {
- var buffer = t_buffer;
- if (buffer != null && buffer.Length >= minimumSize)
- {
- t_buffer = null;
- return buffer;
- }
- return ArrayPool.Shared.Rent(Math.Max(minimumSize, InitialBufferSize));
- }
-
- private static void ReturnBuffer(byte[] buffer)
- {
- if (buffer.Length <= InitialBufferSize * 4)
- {
- t_buffer = buffer;
- }
- else
- {
- ArrayPool.Shared.Return(buffer);
- }
- }
-
public static void ReadDataElement(Envelope env, string key, string value)
{
try
@@ -234,89 +203,42 @@ private static Envelope readSingle(BinaryReader br)
public static byte[] Serialize(IList messages)
{
- // Estimate size: 4 bytes for count + ~500 bytes per message average
- var estimatedSize = 4 + (messages.Count * 500);
- var buffer = RentBuffer(estimatedSize);
- try
- {
- using var stream = new MemoryStream(buffer, 0, buffer.Length, writable: true, publiclyVisible: true);
- using var writer = new BinaryWriter(stream);
- writer.Write(messages.Count);
- foreach (var message in messages) writeSingle(writer, message);
- writer.Flush();
-
- var length = (int)stream.Position;
- var result = new byte[length];
- Buffer.BlockCopy(buffer, 0, result, 0, length);
- return result;
- }
- catch (NotSupportedException)
- {
- // Buffer was too small, fall back to expandable stream
- ReturnBuffer(buffer);
- using var stream = new MemoryStream();
- using var writer = new BinaryWriter(stream);
- writer.Write(messages.Count);
- foreach (var message in messages) writeSingle(writer, message);
- writer.Flush();
- return stream.ToArray();
- }
- finally
- {
- ReturnBuffer(buffer);
- }
+ using var stream = new MemoryStream();
+ using var writer = new BinaryWriter(stream);
+ writer.Write(messages.Count);
+ foreach (var message in messages) writeSingle(writer, message);
+ writer.Flush();
+ return stream.ToArray();
}
public static byte[] Serialize(Envelope env)
{
- // Estimate size based on data length + headers (~200 bytes overhead)
- var dataLength = env.Data?.Length ?? 0;
- var estimatedSize = dataLength + 512;
- var buffer = RentBuffer(estimatedSize);
- try
- {
- using var stream = new MemoryStream(buffer, 0, buffer.Length, writable: true, publiclyVisible: true);
- using var writer = new BinaryWriter(stream);
- writeSingle(writer, env);
- writer.Flush();
-
- var length = (int)stream.Position;
- var result = new byte[length];
- Buffer.BlockCopy(buffer, 0, result, 0, length);
- return result;
- }
- catch (NotSupportedException)
- {
- // Buffer was too small, fall back to expandable stream
- ReturnBuffer(buffer);
- using var stream = new MemoryStream();
- using var writer = new BinaryWriter(stream);
- writeSingle(writer, env);
- writer.Flush();
- return stream.ToArray();
- }
- finally
- {
- ReturnBuffer(buffer);
- }
+ using var stream = new MemoryStream();
+ using var writer = new BinaryWriter(stream);
+ writeSingle(writer, env);
+ writer.Flush();
+ return stream.ToArray();
}
private static void writeSingle(BinaryWriter writer, Envelope env)
{
writer.Write(env.SentAt.UtcDateTime.ToBinary());
- // Write placeholder for header count, remember position
- var countPosition = writer.BaseStream.Position;
- writer.Write(0); // placeholder
+ writer.Flush();
+
+ using (var headerData = new MemoryStream())
+ {
+ using (var headerWriter = new BinaryWriter(headerData))
+ {
+ var count = writeHeaders(headerWriter, env);
+ headerWriter.Flush();
- // Write headers directly to the stream
- var count = writeHeaders(writer, env);
+ writer.Write(count);
- // Go back and write the actual count
- var currentPosition = writer.BaseStream.Position;
- writer.BaseStream.Position = countPosition;
- writer.Write(count);
- writer.BaseStream.Position = currentPosition;
+ headerData.Position = 0;
+ headerData.CopyTo(writer.BaseStream);
+ }
+ }
writer.Write(env.Data!.Length);
writer.Write(env.Data);
@@ -339,8 +261,11 @@ private static int writeHeaders(BinaryWriter writer, Envelope env)
writer.WriteProp(ref count, EnvelopeConstants.TopicNameKey, env.TopicName);
- // Use cached joined string to avoid allocation on every serialization
- writer.WriteProp(ref count, EnvelopeConstants.AcceptedContentTypesKey, env.AcceptedContentTypesJoined);
+ if (env.AcceptedContentTypes.Length != 0)
+ {
+ writer.WriteProp(ref count, EnvelopeConstants.AcceptedContentTypesKey,
+ string.Join(",", env.AcceptedContentTypes));
+ }
writer.WriteProp(ref count, EnvelopeConstants.IdKey, env.Id);
writer.WriteProp(ref count, EnvelopeConstants.ReplyRequestedKey, env.ReplyRequested);