Skip to content

Commit edb9846

Browse files
calvinmetcalfMylesBorins
authored andcommitted
stream: remove usage of *State.highWaterMark
Replaced _readableState.highWaterMark with a .readableHighWaterMark getter and _writableState.highWaterMark with a .writableHighWaterMark getter. The getters are non-enumerable because they break some prototype manipulation that happen in the ecosystem. Ref: #445. PR-URL: #12860 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
1 parent f321921 commit edb9846

11 files changed

+73
-17
lines changed

doc/api/stream.md

+16
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,14 @@ process.nextTick(() => {
437437

438438
See also: [`writable.cork()`][].
439439

440+
##### writable.writableHighWaterMark
441+
<!-- YAML
442+
added: REPLACEME
443+
-->
444+
445+
Return the value of `highWaterMark` passed when constructing this
446+
`Writable`.
447+
440448
##### writable.write(chunk[, encoding][, callback])
441449
<!-- YAML
442450
added: v0.9.4
@@ -879,6 +887,14 @@ to prevent memory leaks.
879887
never closed until the Node.js process exits, regardless of the specified
880888
options.
881889

890+
##### readable.readableHighWaterMark
891+
<!-- YAML
892+
added: REPLACEME
893+
-->
894+
895+
Return the value of `highWaterMark` passed when constructing this
896+
`Readable`.
897+
882898
##### readable.read([size])
883899
<!-- YAML
884900
added: v0.9.4

lib/_http_server.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -373,13 +373,13 @@ function connectionListener(socket) {
373373
function updateOutgoingData(socket, state, delta) {
374374
state.outgoingData += delta;
375375
if (socket._paused &&
376-
state.outgoingData < socket._writableState.highWaterMark) {
376+
state.outgoingData < socket.writeHWM) {
377377
return socketOnDrain(socket, state);
378378
}
379379
}
380380

381381
function socketOnDrain(socket, state) {
382-
var needPause = state.outgoingData > socket._writableState.highWaterMark;
382+
var needPause = state.outgoingData > socket.writeHWM;
383383

384384
// If we previously paused, then start reading again.
385385
if (socket._paused && !needPause) {
@@ -569,7 +569,7 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
569569
// pipelined requests that may never be resolved.
570570
if (!socket._paused) {
571571
var ws = socket._writableState;
572-
if (ws.needDrain || state.outgoingData >= ws.highWaterMark) {
572+
if (ws.needDrain || state.outgoingData >= socket.writableHighWaterMark) {
573573
socket._paused = true;
574574
// We also need to pause the parser, but don't do that until after
575575
// the call to execute, because we may still be processing the last

lib/_stream_duplex.js

+18-5
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,14 @@ const Writable = require('_stream_writable');
3434

3535
util.inherits(Duplex, Readable);
3636

37-
var keys = Object.keys(Writable.prototype);
38-
for (var v = 0; v < keys.length; v++) {
39-
var method = keys[v];
40-
if (!Duplex.prototype[method])
41-
Duplex.prototype[method] = Writable.prototype[method];
37+
{
38+
// avoid scope creep, the keys array can then be collected
39+
const keys = Object.keys(Writable.prototype);
40+
for (var v = 0; v < keys.length; v++) {
41+
const method = keys[v];
42+
if (!Duplex.prototype[method])
43+
Duplex.prototype[method] = Writable.prototype[method];
44+
}
4245
}
4346

4447
function Duplex(options) {
@@ -61,6 +64,16 @@ function Duplex(options) {
6164
this.once('end', onend);
6265
}
6366

67+
Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', {
68+
// making it explicit this property is not enumerable
69+
// because otherwise some prototype manipulation in
70+
// userland will fail
71+
enumerable: false,
72+
get: function() {
73+
return this._writableState.highWaterMark;
74+
}
75+
});
76+
6477
// the no-half-open enforcer
6578
function onend() {
6679
// if we allow half-open state, or if the writable side ended,

lib/_stream_readable.js

+9
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,15 @@ Readable.prototype.wrap = function(stream) {
916916
return self;
917917
};
918918

919+
Object.defineProperty(Readable.prototype, 'readableHighWaterMark', {
920+
// making it explicit this property is not enumerable
921+
// because otherwise some prototype manipulation in
922+
// userland will fail
923+
enumerable: false,
924+
get: function() {
925+
return this._readableState.highWaterMark;
926+
}
927+
});
919928

920929
// exposed for testing purposes only.
921930
Readable._fromList = fromList;

lib/_stream_writable.js

+10
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,16 @@ function decodeChunk(state, chunk, encoding) {
334334
return chunk;
335335
}
336336

337+
Object.defineProperty(Writable.prototype, 'writableHighWaterMark', {
338+
// making it explicit this property is not enumerable
339+
// because otherwise some prototype manipulation in
340+
// userland will fail
341+
enumerable: false,
342+
get: function() {
343+
return this._writableState.highWaterMark;
344+
}
345+
});
346+
337347
// if we're already writing something, then just put this
338348
// in the queue, and wait our turn. Otherwise, call _write
339349
// If we return false, then we need a drain event, so set that flag.

lib/fs.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2072,7 +2072,7 @@ ReadStream.prototype._read = function(n) {
20722072

20732073
if (!pool || pool.length - pool.used < kMinPoolSpace) {
20742074
// discard the old pool.
2075-
allocNewPool(this._readableState.highWaterMark);
2075+
allocNewPool(this.readableHighWaterMark);
20762076
}
20772077

20782078
// Grab another reference to the pool in the case that while we're

test/parallel/test-http-pipeline-regr-3508.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const server = http.createServer(function(req, res) {
3030
res.end(chunk);
3131
}
3232
size += res.outputSize;
33-
if (size <= req.socket._writableState.highWaterMark) {
33+
if (size <= req.socket.writableHighWaterMark) {
3434
more();
3535
return;
3636
}

test/parallel/test-stream-big-packet.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ s1.pipe(s3);
4444
s2.pipe(s3, { end: false });
4545

4646
// We must write a buffer larger than highWaterMark
47-
const big = Buffer.alloc(s1._writableState.highWaterMark + 1, 'x');
47+
const big = Buffer.alloc(s1.writableHighWaterMark + 1, 'x');
4848

4949
// Since big is larger than highWaterMark, it will be buffered internally.
5050
assert(!s1.write(big));

test/parallel/test-stream-readable-flow-recursion.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ flow(stream, 5000, function() {
6868
process.on('exit', function(code) {
6969
assert.strictEqual(reads, 2);
7070
// we pushed up the high water mark
71-
assert.strictEqual(stream._readableState.highWaterMark, 8192);
71+
assert.strictEqual(stream.readableHighWaterMark, 8192);
7272
// length is 0 right now, because we pulled it all out.
7373
assert.strictEqual(stream._readableState.length, 0);
7474
assert(!code);

test/parallel/test-stream-transform-split-objectmode.js

+12-4
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,12 @@ const parser = new Transform({ readableObjectMode: true });
2929

3030
assert(parser._readableState.objectMode);
3131
assert(!parser._writableState.objectMode);
32-
assert.strictEqual(parser._readableState.highWaterMark, 16);
33-
assert.strictEqual(parser._writableState.highWaterMark, 16 * 1024);
32+
assert.strictEqual(parser.readableHighWaterMark, 16);
33+
assert.strictEqual(parser.writableHighWaterMark, 16 * 1024);
34+
assert.strictEqual(parser.readableHighWaterMark,
35+
parser._readableState.highWaterMark);
36+
assert.strictEqual(parser.writableHighWaterMark,
37+
parser._writableState.highWaterMark);
3438

3539
parser._transform = function(chunk, enc, callback) {
3640
callback(null, { val: chunk[0] });
@@ -53,8 +57,12 @@ const serializer = new Transform({ writableObjectMode: true });
5357

5458
assert(!serializer._readableState.objectMode);
5559
assert(serializer._writableState.objectMode);
56-
assert.strictEqual(serializer._readableState.highWaterMark, 16 * 1024);
57-
assert.strictEqual(serializer._writableState.highWaterMark, 16);
60+
assert.strictEqual(serializer.readableHighWaterMark, 16 * 1024);
61+
assert.strictEqual(serializer.writableHighWaterMark, 16);
62+
assert.strictEqual(parser.readableHighWaterMark,
63+
parser._readableState.highWaterMark);
64+
assert.strictEqual(parser.writableHighWaterMark,
65+
parser._writableState.highWaterMark);
5866

5967
serializer._transform = function(obj, _, callback) {
6068
callback(null, Buffer.from([obj.val]));

test/parallel/test-stream2-unpipe-leak.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,6 @@ console.error(src._readableState);
6868
process.on('exit', function() {
6969
src._readableState.buffer.length = 0;
7070
console.error(src._readableState);
71-
assert(src._readableState.length >= src._readableState.highWaterMark);
71+
assert(src._readableState.length >= src.readableHighWaterMark);
7272
console.log('ok');
7373
});

0 commit comments

Comments
 (0)