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

align with node streams #47

Merged
merged 6 commits into from
Feb 4, 2021
Merged

align with node streams #47

merged 6 commits into from
Feb 4, 2021

Conversation

ronag
Copy link
Contributor

@ronag ronag commented Sep 25, 2019

This refactors destroy to better align with the node stream invariants.

@@ -96,7 +101,6 @@ class MultiStream extends stream.Readable {
_gotNextStream (stream) {
if (!stream) {
this.push(null)
this.destroy()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use autoDestroy to ensure proper event ordering

if (!readableEnded && !stream.destroyed) {
const err = new Error('ERR_STREAM_PREMATURE_CLOSE')
err.code = 'ERR_STREAM_PREMATURE_CLOSE'
this.destroy(err)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

close without end is an error

@@ -118,6 +127,7 @@ class MultiStream extends stream.Readable {
stream.removeListener('readable', onReadable)
stream.removeListener('end', onEnd)
stream.removeListener('close', onClose)
stream.destroy()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not all streams will auto destroy on 'end', so we should explicitly destroy just to make sure we don't have any dangling resources in buggy streams

@@ -58,19 +57,25 @@ class MultiStream extends stream.Readable {
this._forwarding = false
}

destroy (err) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not override destroy as that will bypass important teardown logic and event ordering.

This refactors destroy to better align with the node stream
invariants.
index.js Outdated Show resolved Hide resolved
index.js Show resolved Hide resolved
index.js Outdated Show resolved Hide resolved
@mafintosh
Copy link
Collaborator

I think this looks good.

I'll let @feross click review as I don't want to imply any warranty 🤣 I get enough "frustrated stream breakage github issues" as is.

@ronag
Copy link
Contributor Author

ronag commented Sep 25, 2019

@mafintosh I took this one step further... though I'm not sure if it's maybe too much changes... what do you think ronag#1?

@feross
Copy link
Owner

feross commented Sep 30, 2019

FYI - I won't have time to review this for a while. Will do as soon as I can.

@pcothenet
Copy link

@feross @ronag this fixes an important issue for us. Not sure how tbh, but a recent update introduced a "premature close" error. Using @ronag branch fixes it.

@alxhotel
Copy link

alxhotel commented Jan 7, 2020

I agree with @pcothenet.

This PR also fixes the premature close error in Webtorrent.

@ronag
Copy link
Contributor Author

ronag commented Jan 7, 2020

I'm more than happy to help out here. But repo admin needs to review and eventually merge.

@goto-bus-stop
Copy link

@feross will you have time for this in the near future? the PR seems to work pretty well on my end!

@pcothenet
Copy link

@feross FYI: still no issue with this PR on production for us after 6 months.

@artembatura
Copy link

artembatura commented Aug 28, 2020

I'd recommend to use this approach, for me it works in more cases correctly.

const merge = (...streams) => {
  let pass = new PassThrough();
  let waiting = streams.length;

  for (const stream of streams) {
    pass = stream.pipe(pass, { end: false });
    stream.once('end', () => --waiting === 0 && pass.emit('end'));
  }

  return pass;
};

P.S. I tried both multistream and @nearform/multistream

Given from https://stackoverflow.com/questions/16431163/concatenate-two-or-n-streams

@feross
Copy link
Owner

feross commented Nov 3, 2020

I'm happy to merge this, but the conflicts need to be fixed.

@mafintosh Does this still look good to merge?

@feross feross requested a review from mafintosh November 4, 2020 22:52
@feross feross self-assigned this Nov 13, 2020
index.js Show resolved Hide resolved
index.js Outdated Show resolved Hide resolved
@mafintosh
Copy link
Collaborator

👍 from me

@feross
Copy link
Owner

feross commented Nov 24, 2020

@ronag Looks like this still has conflicts – can you resolve those and then this looks ready to merge!

Copy link
Owner

@feross feross left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good – just one final bit of feedback

stream
.on('error', callback)
.on('close', () => callback()))
.destroy(err, callback)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the destroy() method really take a callback?

index.js Show resolved Hide resolved
@feross feross merged commit d3ee23c into feross:master Feb 4, 2021
@feross
Copy link
Owner

feross commented Feb 4, 2021

Sorry the delay everyone. This is now merged and released as 4.1.0!

feross added a commit to webtorrent/webtorrent that referenced this pull request Feb 4, 2021
Since feross/multistream#47 was merged, we shouldn't need to pin this anymore.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants