当stdout超过缓冲区大小时,为什么仅发出一个'数据'事件?

问题描述 投票:0回答:1

背景:https://github.com/Almenon/AREPL-vscode/pull/332(很多,我建议先阅读下面的内容)

我假设到达highWaterMark时节点刷新标准输出。它是否正确?根据此stackoveflow,答案似乎是肯定的。假设这样,如果超出了高水位线,则多余的字符应该再次刷新,对吧?

Node似乎忽略了高水位标记,并且仅冲洗一次,而不管缓冲区大小如何。

示例代码以预期/实际结果重现了我的问题:

import { spawn } from "child_process"

// 8192*2 (16384 aka 16KB) is the highWaterMark (aka buffer size?)
const node_process = spawn("node", ["-e", "process.stdout.write('a'.repeat(8192*2+1));setTimeout(()=>{console.log('done')},4000)"])

node_process.on('error', err => console.error(err))

let numFlushes = 0
node_process.stdout.on('data', (buffer: Buffer) => {
    numFlushes += 1
    const str = buffer.toString()
    console.log(`flush number: ${numFlushes}\
    Buffer length: ${buffer.length}`)
    if (buffer.length < 20) console.log(str)
})

/*
Expected result: 3 flushes, one when highWaterMark is reached, another with rest of stdout, final with done log
Acutal result: 2 flushes. All of stdout is recieved at once. 4 seconds later comes the done log.
Related docs: https://nodejs.org/docs/latest-v12.x/api/stream.html#stream_buffering
OUTPUT (courtesy of quokka)
flush number: 1    Buffer length: 16385
  at ​​​`flush number: ${ numFlushes }\ Buff...​​​ ​personal/test_node_buffer.ts:11:4
flush number: 2    Buffer length: 11
  at ​​​`flush number: ${ numFlushes }\ Buff...​​​ ​personal/test_node_buffer.ts:11:4
done
  at ​​​str​​​ ​personal/test_node_buffer.ts:13:8
*/

https://gist.github.com/Almenon/6286ca1baf0714b56dc133e03728eb12

我已经在Windows 10上对此进行了测试。在Linux上,如果您执行* 8 + 2,则按预期有3次刷新。奇。除此之外,这两个平台具有相同的行为。

https://repl.it/@almenon/testBufferSize

node.js sockets stream buffer stdout
1个回答
0
投票

https://github.com/nodejs/node/issues/33465

节点“在感觉到它时发出数据事件”

是的,这就是答案。我计划在接受之前进一步研究它以确认。

© www.soinside.com 2019 - 2024. All rights reserved.