From 72d02008082f825e737d531a82d3a96f217e78eb Mon Sep 17 00:00:00 2001 From: Yuya Tanaka Date: Sun, 1 Jan 2017 01:09:52 +0900 Subject: [PATCH] child_process: optimize IPC for large data Squashed from: - child_process: stop indexOf() on whole IPC buffer - child_process: get rid of forEach() and slice() in IPC - child_process: get rid of another forEach() in IPC Fixes: https://github.com/nodejs/node/issues/3145 PR-URL: https://github.com/nodejs/node/pull/10557 Reviewed-By: Ben Noordhuis Reviewed-By: Anna Henningsen --- lib/internal/child_process.js | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js index a03b6cefd5c6..6033e9705e49 100644 --- a/lib/internal/child_process.js +++ b/lib/internal/child_process.js @@ -447,14 +447,20 @@ function setupChannel(target, channel) { channel.onread = function(nread, pool, recvHandle) { // TODO(bnoordhuis) Check that nread > 0. if (pool) { - jsonBuffer += decoder.write(pool); - - var i, start = 0; + // Linebreak is used as a message end sign + var chunks = decoder.write(pool).split('\n'); + var numCompleteChunks = chunks.length - 1; + // Last line does not have trailing linebreak + var incompleteChunk = chunks[numCompleteChunks]; + if (numCompleteChunks === 0) { + jsonBuffer += incompleteChunk; + this.buffering = jsonBuffer.length !== 0; + return; + } + chunks[0] = jsonBuffer + chunks[0]; - //Linebreak is used as a message end sign - while ((i = jsonBuffer.indexOf('\n', start)) >= 0) { - var json = jsonBuffer.slice(start, i); - var message = JSON.parse(json); + for (var i = 0; i < numCompleteChunks; i++) { + var message = JSON.parse(chunks[i]); // There will be at most one NODE_HANDLE message in every chunk we // read because SCM_RIGHTS messages don't get coalesced. Make sure @@ -463,10 +469,8 @@ function setupChannel(target, channel) { handleMessage(target, message, recvHandle); else handleMessage(target, message, undefined); - - start = i + 1; } - jsonBuffer = jsonBuffer.slice(start); + jsonBuffer = incompleteChunk; this.buffering = jsonBuffer.length !== 0; } else { @@ -495,9 +499,10 @@ function setupChannel(target, channel) { var queue = target._handleQueue; target._handleQueue = null; - queue.forEach(function(args) { + for (var i = 0; i < queue.length; i++) { + var args = queue[i]; target._send(args.message, args.handle, args.options, args.callback); - }); + } // Process a pending disconnect (if any). if (!target.connected && target._channel && !target._handleQueue)