diff --git a/doc/api/stream.md b/doc/api/stream.md index b7f83a5e1b448a..066d85adc493e1 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -1094,6 +1094,8 @@ buffer will be returned. If the `size` argument is not specified, all of the data contained in the internal buffer will be returned. +The `size` argument must be less than or equal to 1 GB. + The `readable.read()` method should only be called on `Readable` streams operating in paused mode. In flowing mode, `readable.read()` is called automatically until the internal buffer is fully drained. diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index 91cf2f75b07125..71fd74b07bea70 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -375,10 +375,11 @@ Readable.prototype.setEncoding = function(enc) { return this; }; -// Don't raise the hwm > 8MB -const MAX_HWM = 0x800000; +// Don't raise the hwm > 1GB +const MAX_HWM = 0x40000000; function computeNewHighWaterMark(n) { if (n >= MAX_HWM) { + // TODO(ronag): Throw ERR_VALUE_OUT_OF_RANGE. n = MAX_HWM; } else { // Get the next highest power of 2 to prevent increasing hwm excessively in diff --git a/test/parallel/test-readable-large-hwm.js b/test/parallel/test-readable-large-hwm.js new file mode 100644 index 00000000000000..d5bf25bc0e61c1 --- /dev/null +++ b/test/parallel/test-readable-large-hwm.js @@ -0,0 +1,27 @@ +'use strict'; +const common = require('../common'); +const { Readable } = require('stream'); + +// Make sure that readable completes +// even when reading larger buffer. +const bufferSize = 10 * 1024 * 1024; +let n = 0; +const r = new Readable({ + read() { + // Try to fill readable buffer piece by piece. + r.push(Buffer.alloc(bufferSize / 10)); + + if (n++ > 10) { + r.push(null); + } + } +}); + +r.on('readable', () => { + while (true) { + const ret = r.read(bufferSize); + if (ret === null) + break; + } +}); +r.on('end', common.mustCall());