mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-23 01:58:29 +00:00
Serialize node invocationInfo JSON directly to stream to avoid running out of memory
Fixed only for SocketNodeInstance, as it deals nicely with streams. Previously ~30MB of JSON text and 32-bit IIS Express would result in an OutOfMemoryException at the GetBytes method, which is now fixed by writing the JSON string directly to the stream and not handling it as a string in between.
This commit is contained in:
committed by
Steve Sanderson
parent
c33b227331
commit
1d76284e25
@@ -33,6 +33,9 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
||||
TypeNameHandling = TypeNameHandling.None
|
||||
};
|
||||
|
||||
private readonly static int streamBufferSize = 16 * 1024;
|
||||
private readonly static UTF8Encoding utf8EncodingWithoutBom = new UTF8Encoding(false);
|
||||
|
||||
private readonly SemaphoreSlim _connectionCreationSemaphore = new SemaphoreSlim(1);
|
||||
private bool _connectionHasFailed;
|
||||
private StreamConnection _physicalConnection;
|
||||
@@ -89,7 +92,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
||||
virtualConnection = _virtualConnectionClient.OpenVirtualConnection();
|
||||
|
||||
// Send request
|
||||
await WriteJsonLineAsync(virtualConnection, invocationInfo, cancellationToken);
|
||||
WriteJsonLine(virtualConnection, invocationInfo, cancellationToken);
|
||||
|
||||
// Determine what kind of response format is expected
|
||||
if (typeof(T) == typeof(Stream))
|
||||
@@ -169,11 +172,20 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
private static async Task WriteJsonLineAsync(Stream stream, object serializableObject, CancellationToken cancellationToken)
|
||||
private static void WriteJsonLine(Stream stream, object serializableObject, CancellationToken cancellationToken)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(serializableObject, jsonSerializerSettings);
|
||||
var bytes = Encoding.UTF8.GetBytes(json + '\n');
|
||||
await stream.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
|
||||
using (var streamWriter = new StreamWriter(stream, utf8EncodingWithoutBom, streamBufferSize, true))
|
||||
using (var jsonWriter = new JsonTextWriter(streamWriter))
|
||||
{
|
||||
jsonWriter.CloseOutput = false;
|
||||
|
||||
var serializer = JsonSerializer.Create(jsonSerializerSettings);
|
||||
serializer.Serialize(jsonWriter, serializableObject);
|
||||
jsonWriter.Flush();
|
||||
|
||||
streamWriter.WriteLine();
|
||||
streamWriter.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<T> ReadJsonAsync<T>(Stream stream, CancellationToken cancellationToken)
|
||||
@@ -184,7 +196,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
||||
|
||||
private static async Task<byte[]> ReadAllBytesAsync(Stream input, CancellationToken cancellationToken)
|
||||
{
|
||||
byte[] buffer = new byte[16 * 1024];
|
||||
byte[] buffer = new byte[streamBufferSize];
|
||||
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user