Files
scriptc/tests/fixtures/event-loop/stdio-readable-backpressure.mjs
T
Chris Tate 2c44d3e3ab Stop reading stdin at the read-ahead mark while 'readable' listeners hold it
- With 'readable' listeners the stream stays paused, as in Node: 'data'
  listeners, resume() and a parked for-await read no longer keep the loop
  reading once the held input reaches the 64 KiB mark (or a larger
  read(size)); reading resumes when a read drains it.
- Held input is a list of chunks with a running length, so an arrival
  appends without copying what is already held, and read() joins only the
  bytes it returns.
- New event-loop case: 'readable', 'data' and resume() with no read() for
  400 ms while 1 MiB arrives.
2026-10-23 05:15:45 -05:00

28 lines
864 B
JavaScript

// 'readable', 'data' and resume() together, with no read() for a while:
// 'readable' keeps the stream paused, so it stops reading at its read-ahead
// mark until a read drains it, and 'data' sees what read() returns.
const input = process.stdin;
let draining = false;
let peak = 0;
let dataBytes = 0;
let readBytes = 0;
const drain = () => {
let chunk;
while ((chunk = input.read()) !== null) readBytes += chunk.length;
};
input.on('data', (chunk) => {
dataBytes += chunk.length;
});
input.on('readable', () => {
peak = Math.max(peak, input.readableLength);
if (draining) drain();
});
input.resume();
setTimeout(() => {
peak = Math.max(peak, input.readableLength);
console.log('held below 128 KiB while not draining', peak <= 131072);
draining = true;
drain();
}, 400);
input.on('end', () => console.log('read', readBytes, 'data', dataBytes));