From afba5b5e6dcd89202095dd4433e6b2dcd579e643 Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Fri, 15 Feb 2019 17:19:38 +0100 Subject: [PATCH] stream: make _read() be called indefinitely if the user wants so Fixes: https://github.com/nodejs/node/issues/26097 PR-URL: https://github.com/nodejs/node/pull/26135 Reviewed-By: Luigi Pinca Reviewed-By: Anna Henningsen Reviewed-By: James M Snell Reviewed-By: Ruben Bridgewater --- lib/_stream_readable.js | 3 ++ .../test-stream-readable-infinite-read.js | 32 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 test/parallel/test-stream-readable-infinite-read.js diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index 8433ec802ba7ba..c52bcb88d8a0b8 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -494,6 +494,7 @@ Readable.prototype.read = function(n) { }; function onEofChunk(stream, state) { + debug('onEofChunk'); if (state.ended) return; if (state.decoder) { var chunk = state.decoder.end(); @@ -524,6 +525,7 @@ function onEofChunk(stream, state) { // a nextTick recursion warning, but that's not so bad. function emitReadable(stream) { var state = stream._readableState; + debug('emitReadable', state.needReadable, state.emittedReadable); state.needReadable = false; if (!state.emittedReadable) { debug('emitReadable', state.flowing); @@ -537,6 +539,7 @@ function emitReadable_(stream) { debug('emitReadable_', state.destroyed, state.length, state.ended); if (!state.destroyed && (state.length || state.ended)) { stream.emit('readable'); + state.emittedReadable = false; } // The stream needs another readable event if diff --git a/test/parallel/test-stream-readable-infinite-read.js b/test/parallel/test-stream-readable-infinite-read.js new file mode 100644 index 00000000000000..3df3e39a73ec36 --- /dev/null +++ b/test/parallel/test-stream-readable-infinite-read.js @@ -0,0 +1,32 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { Readable } = require('stream'); + +const buf = Buffer.alloc(8192); + +const readable = new Readable({ + read: common.mustCall(function() { + this.push(buf); + }, 31) +}); + +let i = 0; + +readable.on('readable', common.mustCall(function() { + if (i++ === 10) { + // We will just terminate now. + process.removeAllListeners('readable'); + return; + } + + const data = readable.read(); + // TODO(mcollina): there is something odd in the highWaterMark logic + // investigate. + if (i === 1) { + assert.strictEqual(data.length, 8192 * 2); + } else { + assert.strictEqual(data.length, 8192 * 3); + } +}, 11));