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
|
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 readonly SemaphoreSlim _connectionCreationSemaphore = new SemaphoreSlim(1);
|
||||||
private bool _connectionHasFailed;
|
private bool _connectionHasFailed;
|
||||||
private StreamConnection _physicalConnection;
|
private StreamConnection _physicalConnection;
|
||||||
@@ -89,7 +92,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
virtualConnection = _virtualConnectionClient.OpenVirtualConnection();
|
virtualConnection = _virtualConnectionClient.OpenVirtualConnection();
|
||||||
|
|
||||||
// Send request
|
// Send request
|
||||||
await WriteJsonLineAsync(virtualConnection, invocationInfo, cancellationToken);
|
WriteJsonLine(virtualConnection, invocationInfo, cancellationToken);
|
||||||
|
|
||||||
// Determine what kind of response format is expected
|
// Determine what kind of response format is expected
|
||||||
if (typeof(T) == typeof(Stream))
|
if (typeof(T) == typeof(Stream))
|
||||||
@@ -169,11 +172,20 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
base.Dispose(disposing);
|
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);
|
using (var streamWriter = new StreamWriter(stream, utf8EncodingWithoutBom, streamBufferSize, true))
|
||||||
var bytes = Encoding.UTF8.GetBytes(json + '\n');
|
using (var jsonWriter = new JsonTextWriter(streamWriter))
|
||||||
await stream.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
|
{
|
||||||
|
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)
|
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)
|
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())
|
using (var ms = new MemoryStream())
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user