From 7230e75f09af02e9bef8e784c622c783a3f7ca85 Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Mon, 11 Nov 2024 11:54:42 -0800 Subject: [PATCH 1/6] Code changes to check perf regression fix. --- .../src/Handler/RequestInvokerHandler.cs | 14 +- .../Resource/Container/ContainerCore.Items.cs | 7 +- .../Serializer/CosmosBufferedStreamWrapper.cs | 123 +++++++++++++----- .../src/Serializer/CosmosSerializationUtil.cs | 2 +- 4 files changed, 104 insertions(+), 42 deletions(-) diff --git a/Microsoft.Azure.Cosmos/src/Handler/RequestInvokerHandler.cs b/Microsoft.Azure.Cosmos/src/Handler/RequestInvokerHandler.cs index 3cb3e6c748..93a2f2419d 100644 --- a/Microsoft.Azure.Cosmos/src/Handler/RequestInvokerHandler.cs +++ b/Microsoft.Azure.Cosmos/src/Handler/RequestInvokerHandler.cs @@ -101,13 +101,13 @@ public override async Task SendAsync( ((CosmosTraceDiagnostics)response.Diagnostics).Value.AddOrUpdateDatum("ExcludedRegions", request.RequestOptions.ExcludeRegions); } - if (ConfigurationManager.IsBinaryEncodingEnabled() - && RequestInvokerHandler.IsPointOperationSupportedForBinaryEncoding(request) - && response.Content != null - && response.Content is not CloneableStream) - { - response.Content = await StreamExtension.AsClonableStreamAsync(response.Content, default); - } + //if (ConfigurationManager.IsBinaryEncodingEnabled() + // && RequestInvokerHandler.IsPointOperationSupportedForBinaryEncoding(request) + // && response.Content != null + // && response.Content is not CloneableStream) + //{ + // response.Content = await StreamExtension.AsClonableStreamAsync(response.Content, default); + //} return response; } diff --git a/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.Items.cs b/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.Items.cs index ca7565cd2f..4c058267ab 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.Items.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.Items.cs @@ -926,7 +926,7 @@ private async Task ProcessItemStreamAsync( // Convert Text to Binary Stream. streamPayload = CosmosSerializationUtil.TrySerializeStreamToTargetFormat( targetSerializationFormat: ContainerCore.GetTargetRequestSerializationFormat(), - inputStream: streamPayload == null ? null : await StreamExtension.AsClonableStreamAsync(streamPayload)); + inputStream: streamPayload ?? null); ResponseMessage responseMessage = await this.ClientContext.ProcessResourceOperationStreamAsync( resourceUri: resourceUri, @@ -943,12 +943,11 @@ private async Task ProcessItemStreamAsync( // Convert Binary Stream to Text. if (targetResponseSerializationFormat.HasValue - && (requestOptions == null || !requestOptions.EnableBinaryResponseOnPointOperations) - && responseMessage?.Content is CloneableStream outputCloneableStream) + && (requestOptions == null || !requestOptions.EnableBinaryResponseOnPointOperations)) { responseMessage.Content = CosmosSerializationUtil.TrySerializeStreamToTargetFormat( targetSerializationFormat: targetResponseSerializationFormat.Value, - inputStream: outputCloneableStream); + inputStream: responseMessage?.Content); } return responseMessage; diff --git a/Microsoft.Azure.Cosmos/src/Serializer/CosmosBufferedStreamWrapper.cs b/Microsoft.Azure.Cosmos/src/Serializer/CosmosBufferedStreamWrapper.cs index f59f14931a..3fb0b72965 100644 --- a/Microsoft.Azure.Cosmos/src/Serializer/CosmosBufferedStreamWrapper.cs +++ b/Microsoft.Azure.Cosmos/src/Serializer/CosmosBufferedStreamWrapper.cs @@ -5,8 +5,10 @@ namespace Microsoft.Azure.Cosmos.Serializer { using System; + using System.Diagnostics; using System.IO; - using System.Linq; + using System.Threading; + using System.Threading.Tasks; using Microsoft.Azure.Cosmos.Json; using Microsoft.Azure.Documents; @@ -18,7 +20,7 @@ internal class CosmosBufferedStreamWrapper : Stream /// /// The inner stream being wrapped. /// - private readonly CloneableStream innerStream; + private readonly Stream innerStream; /// /// Indicates whether the inner stream should be disposed. @@ -41,9 +43,13 @@ internal class CosmosBufferedStreamWrapper : Stream /// The input stream to wrap. /// Indicates whether the inner stream should be disposed. public CosmosBufferedStreamWrapper( - CloneableStream inputStream, + Stream inputStream, bool shouldDisposeInnerStream) { + Debug.Assert( + inputStream is CloneableStream || inputStream is MemoryStream, + "The inner stream is neither a memory stream nor a cloneable stream."); + this.innerStream = inputStream ?? throw new ArgumentNullException(nameof(inputStream)); this.shouldDisposeInnerStream = shouldDisposeInnerStream; } @@ -93,7 +99,33 @@ public override int Read(byte[] buffer, int offset, int count) throw new ArgumentNullException(nameof(buffer)); } - return this.innerStream.Read(buffer, offset, count); + if (offset < 0 + || count < 0 + || (buffer.Length - offset) < count + || this.innerStream.Position == this.innerStream.Length) + { + return 0; + } + + int bytesRead = 0; + if (this.hasReadFirstByte + && this.innerStream.Position == 1 + && offset == 0 + && count > 0) + { + buffer[0] = this.firstByteBuffer[0]; + bytesRead = 1; + offset++; + count--; + } + + if (count > 0) + { + int innerBytesRead = this.innerStream.Read(buffer, offset, count); + bytesRead += innerBytesRead; + } + + return bytesRead; } /// @@ -114,7 +146,10 @@ protected override void Dispose(bool disposing) } else { - this.ResetStreamPosition(); + if (this.innerStream.CanSeek) + { + this.innerStream.Position = 0; + } } } @@ -129,11 +164,48 @@ protected override void Dispose(bool disposing) /// public byte[] ReadAll() { - ArraySegment byteSegment = this.innerStream.GetBuffer(); + int count, totalBytes = 0, offset = (int)this.Position, length = (int)this.Length; + byte[] bytes = new byte[length]; - return byteSegment.Array.Length == byteSegment.Count - ? byteSegment.Array - : byteSegment.ToArray(); + while ((count = this.innerStream.Read(bytes, offset, length - offset)) > 0) + { + offset += count; + totalBytes += count; + } + + if (this.hasReadFirstByte) + { + bytes[0] = this.firstByteBuffer[0]; + totalBytes += 1; + } + + return totalBytes > 0 ? bytes : default; + } + + /// + /// Asynchronously reads all bytes from the current position to the end of the stream. + /// + /// + /// A task that represents the asynchronous read operation. The value of the TResult parameter contains a byte array with all the bytes read from the stream, or null if no bytes were read. + /// + public async Task ReadAllAsync(CancellationToken cancellationToken = default) + { + int count, totalBytes = 0, offset = (int)this.Position, length = (int)this.Length; + byte[] bytes = new byte[length]; + + while ((count = await this.innerStream.ReadAsync(bytes, offset, length - offset, cancellationToken)) > 0) + { + offset += count; + totalBytes += count; + } + + if (this.hasReadFirstByte) + { + bytes[0] = this.firstByteBuffer[0]; + totalBytes += 1; + } + + return totalBytes > 0 ? bytes : default; } /// @@ -144,40 +216,31 @@ public byte[] ReadAll() /// public JsonSerializationFormat GetJsonSerializationFormat() { - this.ReadFirstByteAndResetStream(); - - return this.firstByteBuffer[0] switch + this.ReadFirstByte(); + if (this.firstByteBuffer[0] == (byte)JsonSerializationFormat.Binary) { - (byte)JsonSerializationFormat.Binary => JsonSerializationFormat.Binary, - (byte)JsonSerializationFormat.HybridRow => JsonSerializationFormat.HybridRow, - _ => JsonSerializationFormat.Text, - }; + return JsonSerializationFormat.Binary; + } + else + { + return this.firstByteBuffer[0] == (byte)JsonSerializationFormat.HybridRow + ? JsonSerializationFormat.HybridRow + : JsonSerializationFormat.Text; + } } /// - /// Reads the first byte from the inner stream and stores it in the buffer. It also resets the stream position to zero. + /// Reads the first byte from the inner stream and stores it in the buffer. /// /// /// This method sets the flag to true if the first byte is successfully read. /// - private void ReadFirstByteAndResetStream() + private void ReadFirstByte() { if (!this.hasReadFirstByte && this.innerStream.Read(this.firstByteBuffer, 0, 1) > 0) { this.hasReadFirstByte = true; - this.ResetStreamPosition(); - } - } - - /// - /// Resets the inner stream position to zero. - /// - private void ResetStreamPosition() - { - if (this.innerStream.CanSeek) - { - this.innerStream.Position = 0; } } } diff --git a/Microsoft.Azure.Cosmos/src/Serializer/CosmosSerializationUtil.cs b/Microsoft.Azure.Cosmos/src/Serializer/CosmosSerializationUtil.cs index f316b1c18f..6330db006d 100644 --- a/Microsoft.Azure.Cosmos/src/Serializer/CosmosSerializationUtil.cs +++ b/Microsoft.Azure.Cosmos/src/Serializer/CosmosSerializationUtil.cs @@ -50,7 +50,7 @@ internal static string GetStringWithPropertyNamingPolicy(CosmosPropertyNamingPol /// Returns true if the input stream is successfully serialized to the target format, otherwise false. internal static Stream TrySerializeStreamToTargetFormat( JsonSerializationFormat targetSerializationFormat, - CloneableStream inputStream) + Stream inputStream) { if (inputStream == null) { From 86d07c58718ffcd1ee5c34e9cad426fa6cf84dce Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Mon, 11 Nov 2024 12:05:37 -0800 Subject: [PATCH 2/6] Code cleanup for serializers. --- .../Serializer/CosmosJsonDotNetSerializer.cs | 33 +++++++++---------- .../CosmosSystemTextJsonSerializer.cs | 29 ++++++++-------- 2 files changed, 29 insertions(+), 33 deletions(-) diff --git a/Microsoft.Azure.Cosmos/src/Serializer/CosmosJsonDotNetSerializer.cs b/Microsoft.Azure.Cosmos/src/Serializer/CosmosJsonDotNetSerializer.cs index 279bf95c71..c86d2f941e 100644 --- a/Microsoft.Azure.Cosmos/src/Serializer/CosmosJsonDotNetSerializer.cs +++ b/Microsoft.Azure.Cosmos/src/Serializer/CosmosJsonDotNetSerializer.cs @@ -98,29 +98,28 @@ public override T FromStream(Stream stream) JsonSerializer jsonSerializer = this.GetSerializer(); - if (stream is CloneableStream cloneableStream) + using (CosmosBufferedStreamWrapper bufferedStream = new (stream, shouldDisposeInnerStream: false)) { - using (CosmosBufferedStreamWrapper bufferedStream = new (cloneableStream, shouldDisposeInnerStream: false)) + if (bufferedStream.GetJsonSerializationFormat() == Json.JsonSerializationFormat.Binary) { - if (bufferedStream.GetJsonSerializationFormat() == Json.JsonSerializationFormat.Binary) - { - byte[] content = bufferedStream.ReadAll(); + byte[] content = bufferedStream.ReadAll(); - using Json.Interop.CosmosDBToNewtonsoftReader reader = new ( - jsonReader: Json.JsonReader.Create( - jsonSerializationFormat: Json.JsonSerializationFormat.Binary, - buffer: content)); + using Json.Interop.CosmosDBToNewtonsoftReader reader = new ( + jsonReader: Json.JsonReader.Create( + jsonSerializationFormat: Json.JsonSerializationFormat.Binary, + buffer: content)); - return jsonSerializer.Deserialize(reader); - } + return jsonSerializer.Deserialize(reader); } - } - - using (StreamReader sr = new (stream)) - { - using (JsonTextReader jsonTextReader = new (sr)) + else { - return jsonSerializer.Deserialize(jsonTextReader); + using (StreamReader sr = new (bufferedStream)) + { + using (JsonTextReader jsonTextReader = new (sr)) + { + return jsonSerializer.Deserialize(jsonTextReader); + } + } } } } diff --git a/Microsoft.Azure.Cosmos/src/Serializer/CosmosSystemTextJsonSerializer.cs b/Microsoft.Azure.Cosmos/src/Serializer/CosmosSystemTextJsonSerializer.cs index 6fcf5ee2c9..e058ed41c0 100644 --- a/Microsoft.Azure.Cosmos/src/Serializer/CosmosSystemTextJsonSerializer.cs +++ b/Microsoft.Azure.Cosmos/src/Serializer/CosmosSystemTextJsonSerializer.cs @@ -52,28 +52,25 @@ public override T FromStream(Stream stream) using (stream) { - if (stream is Documents.CloneableStream cloneableStream) + using (CosmosBufferedStreamWrapper bufferedStream = new (stream, shouldDisposeInnerStream: false)) { - using (CosmosBufferedStreamWrapper bufferedStream = new (cloneableStream, shouldDisposeInnerStream: false)) + if (bufferedStream.GetJsonSerializationFormat() == JsonSerializationFormat.Binary) { - if (bufferedStream.GetJsonSerializationFormat() == JsonSerializationFormat.Binary) + byte[] content = bufferedStream.ReadAll(); + + if (CosmosObject.TryCreateFromBuffer(content, out CosmosObject cosmosObject)) + { + return System.Text.Json.JsonSerializer.Deserialize(cosmosObject.ToString(), this.jsonSerializerOptions); + } + else { - byte[] content = bufferedStream.ReadAll(); - - if (CosmosObject.TryCreateFromBuffer(content, out CosmosObject cosmosObject)) - { - return System.Text.Json.JsonSerializer.Deserialize(cosmosObject.ToString(), this.jsonSerializerOptions); - } - else - { - using Stream textStream = CosmosSerializationUtil.ConvertToStreamUsingJsonSerializationFormat(content, JsonSerializationFormat.Text); - return this.DeserializeStream(textStream); - } + using Stream textStream = CosmosSerializationUtil.ConvertToStreamUsingJsonSerializationFormat(content, JsonSerializationFormat.Text); + return this.DeserializeStream(textStream); } } - } - return this.DeserializeStream(stream); + return this.DeserializeStream(bufferedStream); + } } } From 7cc5ca5ab47b6b159119a9d66a250ff93ea71485 Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Mon, 11 Nov 2024 12:06:03 -0800 Subject: [PATCH 3/6] Some more cleanup. --- .../src/Handler/RequestInvokerHandler.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Microsoft.Azure.Cosmos/src/Handler/RequestInvokerHandler.cs b/Microsoft.Azure.Cosmos/src/Handler/RequestInvokerHandler.cs index 93a2f2419d..067472d009 100644 --- a/Microsoft.Azure.Cosmos/src/Handler/RequestInvokerHandler.cs +++ b/Microsoft.Azure.Cosmos/src/Handler/RequestInvokerHandler.cs @@ -101,14 +101,6 @@ public override async Task SendAsync( ((CosmosTraceDiagnostics)response.Diagnostics).Value.AddOrUpdateDatum("ExcludedRegions", request.RequestOptions.ExcludeRegions); } - //if (ConfigurationManager.IsBinaryEncodingEnabled() - // && RequestInvokerHandler.IsPointOperationSupportedForBinaryEncoding(request) - // && response.Content != null - // && response.Content is not CloneableStream) - //{ - // response.Content = await StreamExtension.AsClonableStreamAsync(response.Content, default); - //} - return response; } From d243843814358dafb580fd24518fd7502d9c4f03 Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Mon, 11 Nov 2024 16:14:15 -0800 Subject: [PATCH 4/6] Code changes to fix unit tests --- .../Serializer/CosmosBufferedStreamWrapper.cs | 43 ++++++++++--------- .../Serializer/CosmosJsonDotNetSerializer.cs | 12 +++--- .../CosmosSystemTextJsonSerializer.cs | 29 ++++++------- .../CosmosBufferedStreamWrapperTests.cs | 22 ++++++++-- .../CosmosItemUnitTests.cs | 4 +- 5 files changed, 63 insertions(+), 47 deletions(-) diff --git a/Microsoft.Azure.Cosmos/src/Serializer/CosmosBufferedStreamWrapper.cs b/Microsoft.Azure.Cosmos/src/Serializer/CosmosBufferedStreamWrapper.cs index 3fb0b72965..3422366b82 100644 --- a/Microsoft.Azure.Cosmos/src/Serializer/CosmosBufferedStreamWrapper.cs +++ b/Microsoft.Azure.Cosmos/src/Serializer/CosmosBufferedStreamWrapper.cs @@ -46,10 +46,6 @@ public CosmosBufferedStreamWrapper( Stream inputStream, bool shouldDisposeInnerStream) { - Debug.Assert( - inputStream is CloneableStream || inputStream is MemoryStream, - "The inner stream is neither a memory stream nor a cloneable stream."); - this.innerStream = inputStream ?? throw new ArgumentNullException(nameof(inputStream)); this.shouldDisposeInnerStream = shouldDisposeInnerStream; } @@ -142,14 +138,12 @@ protected override void Dispose(bool disposing) this.Flush(); if (this.shouldDisposeInnerStream) { + Console.WriteLine($"Dispose inner stream called: {this.innerStream.GetType()}"); this.innerStream.Dispose(); } else { - if (this.innerStream.CanSeek) - { - this.innerStream.Position = 0; - } + this.ResetStreamPosition(); } } @@ -216,31 +210,40 @@ public async Task ReadAllAsync(CancellationToken cancellationToken = def /// public JsonSerializationFormat GetJsonSerializationFormat() { - this.ReadFirstByte(); - if (this.firstByteBuffer[0] == (byte)JsonSerializationFormat.Binary) - { - return JsonSerializationFormat.Binary; - } - else + this.ReadFirstByteAndResetStream(); + + return this.firstByteBuffer[0] switch { - return this.firstByteBuffer[0] == (byte)JsonSerializationFormat.HybridRow - ? JsonSerializationFormat.HybridRow - : JsonSerializationFormat.Text; - } + (byte)JsonSerializationFormat.Binary => JsonSerializationFormat.Binary, + (byte)JsonSerializationFormat.HybridRow => JsonSerializationFormat.HybridRow, + _ => JsonSerializationFormat.Text, + }; } /// - /// Reads the first byte from the inner stream and stores it in the buffer. + /// Reads the first byte from the inner stream and stores it in the buffer. It also resets the stream position to zero. /// /// /// This method sets the flag to true if the first byte is successfully read. /// - private void ReadFirstByte() + private void ReadFirstByteAndResetStream() { if (!this.hasReadFirstByte && this.innerStream.Read(this.firstByteBuffer, 0, 1) > 0) { this.hasReadFirstByte = true; + this.ResetStreamPosition(); + } + } + + /// + /// Resets the inner stream position to zero. + /// + private void ResetStreamPosition() + { + if (this.innerStream.CanSeek) + { + this.innerStream.Position = 0; } } } diff --git a/Microsoft.Azure.Cosmos/src/Serializer/CosmosJsonDotNetSerializer.cs b/Microsoft.Azure.Cosmos/src/Serializer/CosmosJsonDotNetSerializer.cs index c86d2f941e..195266ba4c 100644 --- a/Microsoft.Azure.Cosmos/src/Serializer/CosmosJsonDotNetSerializer.cs +++ b/Microsoft.Azure.Cosmos/src/Serializer/CosmosJsonDotNetSerializer.cs @@ -91,15 +91,15 @@ public override T FromStream(Stream stream) { using (stream) { - if (typeof(Stream).IsAssignableFrom(typeof(T))) + using (CosmosBufferedStreamWrapper bufferedStream = new (stream, shouldDisposeInnerStream: true)) { - return (T)(object)stream; - } + if (typeof(Stream).IsAssignableFrom(typeof(T))) + { + return (T)(object)stream; + } - JsonSerializer jsonSerializer = this.GetSerializer(); + JsonSerializer jsonSerializer = this.GetSerializer(); - using (CosmosBufferedStreamWrapper bufferedStream = new (stream, shouldDisposeInnerStream: false)) - { if (bufferedStream.GetJsonSerializationFormat() == Json.JsonSerializationFormat.Binary) { byte[] content = bufferedStream.ReadAll(); diff --git a/Microsoft.Azure.Cosmos/src/Serializer/CosmosSystemTextJsonSerializer.cs b/Microsoft.Azure.Cosmos/src/Serializer/CosmosSystemTextJsonSerializer.cs index e058ed41c0..4a4940365a 100644 --- a/Microsoft.Azure.Cosmos/src/Serializer/CosmosSystemTextJsonSerializer.cs +++ b/Microsoft.Azure.Cosmos/src/Serializer/CosmosSystemTextJsonSerializer.cs @@ -50,27 +50,24 @@ public override T FromStream(Stream stream) return default; } - using (stream) + using (CosmosBufferedStreamWrapper bufferedStream = new (stream, shouldDisposeInnerStream: true)) { - using (CosmosBufferedStreamWrapper bufferedStream = new (stream, shouldDisposeInnerStream: false)) + if (bufferedStream.GetJsonSerializationFormat() == JsonSerializationFormat.Binary) { - if (bufferedStream.GetJsonSerializationFormat() == JsonSerializationFormat.Binary) + byte[] content = bufferedStream.ReadAll(); + + if (CosmosObject.TryCreateFromBuffer(content, out CosmosObject cosmosObject)) { - byte[] content = bufferedStream.ReadAll(); - - if (CosmosObject.TryCreateFromBuffer(content, out CosmosObject cosmosObject)) - { - return System.Text.Json.JsonSerializer.Deserialize(cosmosObject.ToString(), this.jsonSerializerOptions); - } - else - { - using Stream textStream = CosmosSerializationUtil.ConvertToStreamUsingJsonSerializationFormat(content, JsonSerializationFormat.Text); - return this.DeserializeStream(textStream); - } + return System.Text.Json.JsonSerializer.Deserialize(cosmosObject.ToString(), this.jsonSerializerOptions); + } + else + { + using Stream textStream = CosmosSerializationUtil.ConvertToStreamUsingJsonSerializationFormat(content, JsonSerializationFormat.Text); + return this.DeserializeStream(textStream); } - - return this.DeserializeStream(bufferedStream); } + + return this.DeserializeStream(bufferedStream); } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosBufferedStreamWrapperTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosBufferedStreamWrapperTests.cs index 0d8e2f4cc3..f2004dee54 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosBufferedStreamWrapperTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosBufferedStreamWrapperTests.cs @@ -176,19 +176,23 @@ public async Task TestWriteAndRead() } } - internal class NonSeekableMemoryStream : Stream + internal class NonSeekableMemoryStream : Stream, IDisposable { private readonly byte[] buffer; private int position; + private bool writable; // Can user write to this stream? + private bool isOpen; // Is this stream open or closed? public NonSeekableMemoryStream(byte[] data) { this.buffer = data; + this.isOpen = true; + this.writable = false; } - public override bool CanRead => true; + public override bool CanRead => this.isOpen; public override bool CanSeek => false; - public override bool CanWrite => false; + public override bool CanWrite => this.writable; public override long Length => this.buffer.Length; @@ -225,6 +229,18 @@ public override void Write(byte[] buffer, int offset, int count) { throw new NotImplementedException(); } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + this.isOpen = false; + this.writable = false; + this.Flush(); + } + + base.Dispose(disposing); + } } } } \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosItemUnitTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosItemUnitTests.cs index a250b0924a..09e540cd71 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosItemUnitTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosItemUnitTests.cs @@ -152,7 +152,8 @@ await VerifyItemOperations( [TestMethod] [DataRow(true, DisplayName = "Test scenario when binary encoding is enabled at client level.")] [DataRow(false, DisplayName = "Test scenario when binary encoding is disabled at client level.")] - public async Task CreateItemAsync_WithNonSeekableStream_ShouldConvertToClonnableStream(bool binaryEncodingEnabledInClient) + public async Task CreateItemAsync_WithNonSeekableStream_ShouldCreateSuccessfully( + bool binaryEncodingEnabledInClient) { try { @@ -183,7 +184,6 @@ public async Task CreateItemAsync_WithNonSeekableStream_ShouldConvertToClonnable Assert.AreEqual(options, request.RequestOptions); Assert.AreEqual(ResourceType.Document, request.ResourceType); Assert.IsNotNull(request.Headers.PartitionKey); - // Assert.AreEqual("\"[4567.1234]\"", request.Headers.PartitionKey); testHandlerHitCount++; bool shouldReturnBinaryResponse = request.Headers[HttpConstants.HttpHeaders.SupportedSerializationFormats] != null From 61ff2150506ad782d9b5d78e9227a7f250129b87 Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Mon, 11 Nov 2024 16:15:50 -0800 Subject: [PATCH 5/6] Mode cleanup --- .../Serializer/CosmosJsonDotNetSerializer.cs | 41 +++++++++---------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/Microsoft.Azure.Cosmos/src/Serializer/CosmosJsonDotNetSerializer.cs b/Microsoft.Azure.Cosmos/src/Serializer/CosmosJsonDotNetSerializer.cs index 195266ba4c..fa7e422300 100644 --- a/Microsoft.Azure.Cosmos/src/Serializer/CosmosJsonDotNetSerializer.cs +++ b/Microsoft.Azure.Cosmos/src/Serializer/CosmosJsonDotNetSerializer.cs @@ -89,36 +89,33 @@ internal CosmosJsonDotNetSerializer( /// The object representing the deserialized stream public override T FromStream(Stream stream) { - using (stream) + using (CosmosBufferedStreamWrapper bufferedStream = new (stream, shouldDisposeInnerStream: true)) { - using (CosmosBufferedStreamWrapper bufferedStream = new (stream, shouldDisposeInnerStream: true)) + if (typeof(Stream).IsAssignableFrom(typeof(T))) { - if (typeof(Stream).IsAssignableFrom(typeof(T))) - { - return (T)(object)stream; - } + return (T)(object)stream; + } - JsonSerializer jsonSerializer = this.GetSerializer(); + JsonSerializer jsonSerializer = this.GetSerializer(); - if (bufferedStream.GetJsonSerializationFormat() == Json.JsonSerializationFormat.Binary) - { - byte[] content = bufferedStream.ReadAll(); + if (bufferedStream.GetJsonSerializationFormat() == Json.JsonSerializationFormat.Binary) + { + byte[] content = bufferedStream.ReadAll(); - using Json.Interop.CosmosDBToNewtonsoftReader reader = new ( - jsonReader: Json.JsonReader.Create( - jsonSerializationFormat: Json.JsonSerializationFormat.Binary, - buffer: content)); + using Json.Interop.CosmosDBToNewtonsoftReader reader = new ( + jsonReader: Json.JsonReader.Create( + jsonSerializationFormat: Json.JsonSerializationFormat.Binary, + buffer: content)); - return jsonSerializer.Deserialize(reader); - } - else + return jsonSerializer.Deserialize(reader); + } + else + { + using (StreamReader sr = new (bufferedStream)) { - using (StreamReader sr = new (bufferedStream)) + using (JsonTextReader jsonTextReader = new (sr)) { - using (JsonTextReader jsonTextReader = new (sr)) - { - return jsonSerializer.Deserialize(jsonTextReader); - } + return jsonSerializer.Deserialize(jsonTextReader); } } } From 3adab73d13f974e07e11e4518a6795e357ca222f Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Mon, 11 Nov 2024 18:59:00 -0800 Subject: [PATCH 6/6] Removing unnecessary print lines. --- .../src/Serializer/CosmosBufferedStreamWrapper.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Microsoft.Azure.Cosmos/src/Serializer/CosmosBufferedStreamWrapper.cs b/Microsoft.Azure.Cosmos/src/Serializer/CosmosBufferedStreamWrapper.cs index 3422366b82..f696317077 100644 --- a/Microsoft.Azure.Cosmos/src/Serializer/CosmosBufferedStreamWrapper.cs +++ b/Microsoft.Azure.Cosmos/src/Serializer/CosmosBufferedStreamWrapper.cs @@ -138,7 +138,6 @@ protected override void Dispose(bool disposing) this.Flush(); if (this.shouldDisposeInnerStream) { - Console.WriteLine($"Dispose inner stream called: {this.innerStream.GetType()}"); this.innerStream.Dispose(); } else