节点 js 中的最大行数:child-process.exec
maximum line count in node js : child-process.exec
问题
Node 的 child-process
有限制吗?
我该如何获取(逐块)一个巨大的命令输出,如 git show with a huge file ?
一般问题
我尝试解析 git show <commit sha>
的结果,并且有一个 巨大的文件(308 344 行)
当 运行 git show > showed_by_git.txt
我有正确的输出,包含所有文件,结果为 118 667 行
当 运行 节点的 child-process
我只检索 32 602 行 ...
我的测试及其结果
我简化了我的代码并使用 child-process
来计算字符数和行数
它在停止流程之前解决。
结果显示它停止在 32 000+ 行而不是预期的 118 667
如果您的存储库包含最近提交的一些 HUUUGE 文件,您可以在家重现
const childProcess = require('child_process')
function fetchCommand (command) {
return new Promise((resolve, reject) => {
const sub = childProcess.exec(command)
let chars = 0
let lines = 0
sub.stdout.on('data', function (chunk) {
chars += chunk.length
lines += chunk.split('\n').length
console.log('chars:' + chars + ' lines:' + lines)
// logs the char and line count on each chunk of data,
// then 'forgets' the data : no memory overloading
})
sub.stdout.on('close', function () {
console.log('CLOSED')
})
sub.stderr.on('error', function (err) {
console.log('ERROR: ' + err.message)
})
})
}
fetchCommand('git show').catch(err => console.log(err))
输出
这是输出:
C:\Users\guill\.code\git2stats>node examples/fetchTest.js
chars:4096 lines:126
chars:73728 lines:2117
chars:131072 lines:3772
chars:176128 lines:5176
chars:229376 lines:6560
chars:262144 lines:7663
chars:323584 lines:9171
chars:393216 lines:11304
chars:462848 lines:13483
chars:475136 lines:13849
chars:507904 lines:14916
chars:536576 lines:15839
chars:573440 lines:17028
chars:618496 lines:18484
chars:688128 lines:20539
chars:737280 lines:22000
chars:765952 lines:22930
chars:794624 lines:23860
chars:823296 lines:24794
chars:892928 lines:26976
chars:962560 lines:29104
chars:991232 lines:30003
chars:1032192 lines:31292
chars:1073152 lines:32602
CLOSED
您可以看到它停在 32 602 行,而这个特定的 git show
有 118 667 行要显示
最后一块
我检查了最后一块数据,看它是否对大文件做了一些特殊的事情,
但我可以确认它停在文件中间
上下文
我正在写一个
git statistics tools,
这个项目进展顺利
因为我可以解析 git log --stat
然后 git show <commit sha>
每次提交
return 令人满意的 json
这是我以前不知道的某种节点 foot-gun。
是的,有一个限制。它配置有 maxBuffer
选项 (see docs),如果您愿意,可以将其设置为 Infinity。可以将其设置为 Infinity 的想法未记录在案。
const sub = childProcess.exec(command, { maxBuffer: Infinity });
我真的很震惊这个限制的存在,我现在将被迫对大量代码进行代码审查,以找到使用 child_process
模块的每个地方,看看我是否需要添加 maxBuffer
选项。
把它当作一个如何设计糟糕界面的例子。
小注
您可能想要处理 sub.on('exit', code => {})
或 sub.on('close')
这是同一件事,因此您可以检查 Git 的退出状态并在状态不为 0 时引发错误. 像这样:
sub.on('exit', code => {
if (code == 0) {
resolve(...);
} else {
reject(...);
}
});
问题
Node 的 child-process
有限制吗?
我该如何获取(逐块)一个巨大的命令输出,如 git show with a huge file ?
一般问题
我尝试解析 git show <commit sha>
的结果,并且有一个 巨大的文件(308 344 行)
当 运行 git show > showed_by_git.txt
我有正确的输出,包含所有文件,结果为 118 667 行
当 运行 节点的 child-process
我只检索 32 602 行 ...
我的测试及其结果
我简化了我的代码并使用 child-process
来计算字符数和行数
它在停止流程之前解决。
结果显示它停止在 32 000+ 行而不是预期的 118 667
如果您的存储库包含最近提交的一些 HUUUGE 文件,您可以在家重现
const childProcess = require('child_process')
function fetchCommand (command) {
return new Promise((resolve, reject) => {
const sub = childProcess.exec(command)
let chars = 0
let lines = 0
sub.stdout.on('data', function (chunk) {
chars += chunk.length
lines += chunk.split('\n').length
console.log('chars:' + chars + ' lines:' + lines)
// logs the char and line count on each chunk of data,
// then 'forgets' the data : no memory overloading
})
sub.stdout.on('close', function () {
console.log('CLOSED')
})
sub.stderr.on('error', function (err) {
console.log('ERROR: ' + err.message)
})
})
}
fetchCommand('git show').catch(err => console.log(err))
输出
这是输出:
C:\Users\guill\.code\git2stats>node examples/fetchTest.js
chars:4096 lines:126
chars:73728 lines:2117
chars:131072 lines:3772
chars:176128 lines:5176
chars:229376 lines:6560
chars:262144 lines:7663
chars:323584 lines:9171
chars:393216 lines:11304
chars:462848 lines:13483
chars:475136 lines:13849
chars:507904 lines:14916
chars:536576 lines:15839
chars:573440 lines:17028
chars:618496 lines:18484
chars:688128 lines:20539
chars:737280 lines:22000
chars:765952 lines:22930
chars:794624 lines:23860
chars:823296 lines:24794
chars:892928 lines:26976
chars:962560 lines:29104
chars:991232 lines:30003
chars:1032192 lines:31292
chars:1073152 lines:32602
CLOSED
您可以看到它停在 32 602 行,而这个特定的 git show
有 118 667 行要显示
最后一块
我检查了最后一块数据,看它是否对大文件做了一些特殊的事情, 但我可以确认它停在文件中间
上下文
我正在写一个
git statistics tools,
这个项目进展顺利
因为我可以解析 git log --stat
然后 git show <commit sha>
每次提交
return 令人满意的 json
这是我以前不知道的某种节点 foot-gun。
是的,有一个限制。它配置有 maxBuffer
选项 (see docs),如果您愿意,可以将其设置为 Infinity。可以将其设置为 Infinity 的想法未记录在案。
const sub = childProcess.exec(command, { maxBuffer: Infinity });
我真的很震惊这个限制的存在,我现在将被迫对大量代码进行代码审查,以找到使用 child_process
模块的每个地方,看看我是否需要添加 maxBuffer
选项。
把它当作一个如何设计糟糕界面的例子。
小注
您可能想要处理 sub.on('exit', code => {})
或 sub.on('close')
这是同一件事,因此您可以检查 Git 的退出状态并在状态不为 0 时引发错误. 像这样:
sub.on('exit', code => {
if (code == 0) {
resolve(...);
} else {
reject(...);
}
});