-
Notifications
You must be signed in to change notification settings - Fork 30.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
child_process: measure buffer length in bytes #6764
Changes from 11 commits
e20ff77
3245de6
7b96b64
2b14b64
221dec5
425128f
2d56158
bce02ef
a8ba111
32925da
ec2cf57
561c798
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
'use strict'; | ||
const common = require('../common.js'); | ||
const bench = common.createBenchmark(main, { | ||
len: [64, 256, 1024, 4096, 32768], | ||
dur: [5] | ||
}); | ||
|
||
const exec = require('child_process').exec; | ||
function main(conf) { | ||
bench.start(); | ||
|
||
const dur = +conf.dur; | ||
const len = +conf.len; | ||
|
||
const msg = `"${'.'.repeat(len)}"`; | ||
msg.match(/./); | ||
const options = {'stdio': ['ignore', 'pipe', 'ignore']}; | ||
// NOTE: Command below assumes bash shell. | ||
const child = exec(`while\n echo ${msg}\ndo :; done\n`, options); | ||
|
||
var bytes = 0; | ||
child.stdout.on('data', function(msg) { | ||
bytes += msg.length; | ||
}); | ||
|
||
setTimeout(function() { | ||
child.kill(); | ||
bench.end(bytes); | ||
}, dur * 1000); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -146,15 +146,13 @@ exports.execFile = function(file /*, args, options, callback*/) { | |
}); | ||
|
||
var encoding; | ||
var _stdout; | ||
var _stderr; | ||
var stdoutState; | ||
var stderrState; | ||
var _stdout = []; | ||
var _stderr = []; | ||
if (options.encoding !== 'buffer' && Buffer.isEncoding(options.encoding)) { | ||
encoding = options.encoding; | ||
_stdout = ''; | ||
_stderr = ''; | ||
} else { | ||
_stdout = []; | ||
_stderr = []; | ||
encoding = null; | ||
} | ||
var stdoutLen = 0; | ||
|
@@ -176,16 +174,23 @@ exports.execFile = function(file /*, args, options, callback*/) { | |
|
||
if (!callback) return; | ||
|
||
// merge chunks | ||
var stdout; | ||
var stderr; | ||
if (!encoding) { | ||
stdout = Buffer.concat(_stdout); | ||
stderr = Buffer.concat(_stderr); | ||
} else { | ||
stdout = _stdout; | ||
stderr = _stderr; | ||
} | ||
var stdout = Buffer.concat(_stdout, stdoutLen); | ||
var stderr = Buffer.concat(_stderr, stderrLen); | ||
|
||
var stdoutEncoding = encoding; | ||
var stderrEncoding = encoding; | ||
|
||
if (stdoutState && stdoutState.decoder) | ||
stdoutEncoding = stdoutState.decoder.encoding; | ||
|
||
if (stderrState && stderrState.decoder) | ||
stderrEncoding = stderrState.decoder.encoding; | ||
|
||
if (stdoutEncoding) | ||
stdout = stdout.toString(stdoutEncoding); | ||
|
||
if (stderrEncoding) | ||
stderr = stderr.toString(stderrEncoding); | ||
|
||
if (ex) { | ||
// Will be handled later | ||
|
@@ -245,39 +250,45 @@ exports.execFile = function(file /*, args, options, callback*/) { | |
} | ||
|
||
if (child.stdout) { | ||
if (encoding) | ||
child.stdout.setEncoding(encoding); | ||
stdoutState = child.stdout._readableState; | ||
|
||
child.stdout.addListener('data', function(chunk) { | ||
stdoutLen += chunk.length; | ||
// If `child.stdout.setEncoding('utf8')` happened in userland, convert | ||
// string to Buffer. | ||
if (stdoutState.decoder) { | ||
chunk = Buffer.from(chunk, stdoutState.decoder.encoding); | ||
} | ||
|
||
stdoutLen += chunk.byteLength; | ||
|
||
if (stdoutLen > options.maxBuffer) { | ||
ex = new Error('stdout maxBuffer exceeded'); | ||
stdoutLen -= chunk.byteLength; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this needed by the way? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mscdex It's needed so that |
||
kill(); | ||
} else { | ||
if (!encoding) | ||
_stdout.push(chunk); | ||
else | ||
_stdout += chunk; | ||
_stdout.push(chunk); | ||
} | ||
}); | ||
} | ||
|
||
if (child.stderr) { | ||
if (encoding) | ||
child.stderr.setEncoding(encoding); | ||
stderrState = child.stderr._readableState; | ||
|
||
child.stderr.addListener('data', function(chunk) { | ||
stderrLen += chunk.length; | ||
// If `child.stderr.setEncoding('utf8')` happened in userland, convert | ||
// string to Buffer. | ||
if (stderrState.decoder) { | ||
chunk = Buffer.from(chunk, stderrState.decoder.encoding); | ||
} | ||
|
||
stderrLen += chunk.byteLength; | ||
|
||
if (stderrLen > options.maxBuffer) { | ||
ex = new Error('stderr maxBuffer exceeded'); | ||
stderrLen -= chunk.byteLength; | ||
kill(); | ||
} else { | ||
if (!encoding) | ||
_stderr.push(chunk); | ||
else | ||
_stderr += chunk; | ||
_stderr.push(chunk); | ||
} | ||
}); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
'use strict'; | ||
const common = require('../common'); | ||
const assert = require('assert'); | ||
const cp = require('child_process'); | ||
const unicode = '中文测试'; // Length = 4, Byte length = 13 | ||
|
||
if (process.argv[2] === 'child') { | ||
console.error(unicode); | ||
} else { | ||
const cmd = `${process.execPath} ${__filename} child`; | ||
|
||
cp.exec(cmd, {maxBuffer: 10}, common.mustCall((err, stdout, stderr) => { | ||
assert.strictEqual(err.message, 'stderr maxBuffer exceeded'); | ||
})); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean any
setEncoding()
call, or specifically w/'utf8'
passed?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean any
setEncoding()
. Will change the comment...