Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

streams: synchronous unpipe() causes data stalls #6890

Closed
bnoordhuis opened this issue May 20, 2016 · 3 comments
Closed

streams: synchronous unpipe() causes data stalls #6890

bnoordhuis opened this issue May 20, 2016 · 3 comments
Labels
confirmed-bug Issues with confirmed bugs. duplicate Issues and PRs that are duplicates of other issues or PRs. stream Issues and PRs related to the stream subsystem.

Comments

@bnoordhuis
Copy link
Member

Continuation of nodejs/node-v0.x-archive#7451. Test case:

var assert = require('assert');
var stream = require('stream');

var a = new stream.Duplex;
var b = new stream.Writable;
var chunks = [];

a._read = function() {};
a._write = a.push.bind(a);
b._write = chunks.push.bind(chunks);

a.pipe(b);
a.write('ping');
a.unpipe(b);

process.on('exit', function() {
  assert(chunks.length > 0);
});

From the original issue:

The unpipe() stops the data from propagating down the chain. That's problematic because I, as a streams2 user that gets slotted somewhere in the chain of handlers, don't know if or when unpipe() gets called.

The observable behavior is that sometimes your pipeline stalls without a clue why. It took me long enough to debug so I strongly doubt that an average user could figure it out.

In the other issue I mentioned that it works with v0.10 but it fails with v0.10.41 and v0.10.45 so it seems there's been a regression somewhere. I think I originally tested with v0.10.26 or v0.10.27-pre.

/cc @nodejs/streams

@bnoordhuis bnoordhuis added confirmed-bug Issues with confirmed bugs. stream Issues and PRs related to the stream subsystem. labels May 20, 2016
@mcollina
Copy link
Member

@bnoordhuis this works:

var assert = require('assert');
var stream = require('stream');

var a = new stream.Duplex;
var b = new stream.Writable;
var chunks = [];

a._read = function() {};
a._write = a.push.bind(a);
b._write = chunks.push.bind(chunks);

a.pipe(b);
a.write('ping');
process.nextTick(function () {
  a.unpipe(b);
})

process.on('exit', function() {
    assert(chunks.length > 0);
});

This happens because resume() is currently wrapped inside nextTick as part of pipe: https://github.com/nodejs/node/blob/master/lib/_stream_readable.js#L717-L734

I am not sure why that was done in that way, and what problem solved.

@addaleax
Copy link
Member

I think this is a duplicate of #1041?

@bnoordhuis
Copy link
Member Author

Looks like it's a duplicate of #1041, yes. I'll close out this one.

@bnoordhuis bnoordhuis added the duplicate Issues and PRs that are duplicates of other issues or PRs. label Mar 5, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug Issues with confirmed bugs. duplicate Issues and PRs that are duplicates of other issues or PRs. stream Issues and PRs related to the stream subsystem.
Projects
None yet
Development

No branches or pull requests

3 participants