Skip to content

Commit

Permalink
stream: allow using .push()/.unshift() during once('data')
Browse files Browse the repository at this point in the history
Previously, the `.push()` or `.unshift()` call would just have jumped
straight to emitting a `'data'` event, even if there were no listeners,
effectively just silently dropping the chunk.

PR-URL: #34957
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Denys Otrishko <shishugi@gmail.com>
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Ricky Zhou <0x19951125@gmail.com>
  • Loading branch information
addaleax committed Sep 22, 2020
1 parent 327d009 commit d44b05b
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/_stream_readable.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,8 @@ function readableAddChunk(stream, chunk, encoding, addToFront) {
}

function addChunk(stream, state, chunk, addToFront) {
if (state.flowing && state.length === 0 && !state.sync) {
if (state.flowing && state.length === 0 && !state.sync &&
stream.listenerCount('data') > 0) {
// Use the guard to avoid creating `Set()` repeatedly
// when we have multiple pipes.
if (state.multiAwaitDrain) {
Expand Down
21 changes: 21 additions & 0 deletions test/parallel/test-stream-readable-add-chunk-during-data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const { Readable } = require('stream');

// Verify that .push() and .unshift() can be called from 'data' listeners.

for (const method of ['push', 'unshift']) {
const r = new Readable({ read() {} });
r.once('data', common.mustCall((chunk) => {
assert.strictEqual(r.readableLength, 0);
r[method](chunk);
assert.strictEqual(r.readableLength, chunk.length);

r.on('data', common.mustCall((chunk) => {
assert.strictEqual(chunk.toString(), 'Hello, world');
}));
}));

r.push('Hello, world');
}

0 comments on commit d44b05b

Please sign in to comment.