Skip to content

Commit

Permalink
child_process: improve ipc write performance
Browse files Browse the repository at this point in the history
PR-URL: #42931
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Zeyu "Alex" Yang <himself65@outlook.com>
  • Loading branch information
CaramelFur authored and targos committed Jul 12, 2022
1 parent cad6d99 commit 3ca9e65
Showing 1 changed file with 22 additions and 12 deletions.
34 changes: 22 additions & 12 deletions lib/internal/child_process/serialization.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ const {
JSONStringify,
StringPrototypeSplit,
ArrayPrototypePush,
ReflectApply,
Symbol,
TypedArrayPrototypeSubarray,
} = primordials;
Expand All @@ -15,7 +14,6 @@ const v8 = require('v8');
const { isArrayBufferView } = require('internal/util/types');
const assert = require('internal/assert');
const { streamBaseState, kLastWriteWasAsync } = internalBinding('stream_wrap');
const { readUInt32BE } = require('internal/buffer');

const kMessageBuffer = Symbol('kMessageBuffer');
const kMessageBufferSize = Symbol('kMessageBufferSize');
Expand Down Expand Up @@ -71,7 +69,12 @@ const advanced = {
while (messageBufferHead.length >= 4) {
// We call `readUInt32BE` manually here, because this is faster than first converting
// it to a buffer and using `readUInt32BE` on that.
const fullMessageSize = ReflectApply(readUInt32BE, messageBufferHead, [0]) + 4;
const fullMessageSize = (
messageBufferHead[0] << 24 |
messageBufferHead[1] << 16 |
messageBufferHead[2] << 8 |
messageBufferHead[3]
) + 4;

if (channel[kMessageBufferSize] < fullMessageSize) break;

Expand Down Expand Up @@ -100,20 +103,27 @@ const advanced = {

writeChannelMessage(channel, req, message, handle) {
const ser = new ChildProcessSerializer();
// Add 4 bytes, to later populate with message length
ser.writeRawBytes(Buffer.allocUnsafe(4));
ser.writeHeader();
ser.writeValue(message);

const serializedMessage = ser.releaseBuffer();
const sizeBuffer = Buffer.allocUnsafe(4);
sizeBuffer.writeUInt32BE(serializedMessage.length);

const buffer = Buffer.concat([
sizeBuffer,
serializedMessage,
]);
const result = channel.writeBuffer(req, buffer, handle);
const serializedMessageLength = serializedMessage.length - 4;

serializedMessage.set([
serializedMessageLength >> 24 & 0xFF,
serializedMessageLength >> 16 & 0xFF,
serializedMessageLength >> 8 & 0xFF,
serializedMessageLength & 0xFF,
], 0);

const result = channel.writeBuffer(req, serializedMessage, handle);

// Mirror what stream_base_commons.js does for Buffer retention.
if (streamBaseState[kLastWriteWasAsync])
req.buffer = buffer;
req.buffer = serializedMessage;

return result;
},
};
Expand Down

0 comments on commit 3ca9e65

Please sign in to comment.