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

Merge streams handling code for http2 streams & net.Socket #19060

Open
addaleax opened this issue Feb 28, 2018 · 26 comments
Open

Merge streams handling code for http2 streams & net.Socket #19060

addaleax opened this issue Feb 28, 2018 · 26 comments
Labels
help wanted Issues that need assistance from volunteers or PRs that need help to proceed. http2 Issues or PRs related to the http2 subsystem. net Issues and PRs related to the net subsystem.

Comments

@addaleax
Copy link
Member

Hey :)

It would be great if we could unify all the code from net and http2 that is only concerned with pushing data to/from the underlying stream, ideally into a common base class of net.Socket and Http2Stream, so that we could also maybe port some of the other native streams (zlib, fs) to using StreamBase on the native side & generally just share a lot of code.

This is probably not an easy task, and probably not doable in one pass, because the http2 and net implementations are always just slightly different, but if anybody wants to try to start working on this, feel free to reach out by commenting here.

@addaleax addaleax added help wanted Issues that need assistance from volunteers or PRs that need help to proceed. net Issues and PRs related to the net subsystem. good first issue Issues that are suitable for first-time contributors. mentor-available http2 Issues or PRs related to the http2 subsystem. labels Feb 28, 2018
@inidaname
Copy link

Hello
@addaleax I will like to take this up, if you point me to the right files
Thank You

@apapirovski
Copy link
Member

@addaleax Are you sure this is a good first issue? This relies on knowledge of both JS & C++, and pretty good grasp of Node streams, net & http2. I would keep it as help wanted but can't imagine someone would want to start contributing with this particular issue.

@addaleax addaleax removed the good first issue Issues that are suitable for first-time contributors. label Mar 1, 2018
@addaleax
Copy link
Member Author

addaleax commented Mar 1, 2018

@apapirovski Yeah, I would talk with people who volunteer for it in more detail about that :) Then again, this doesn’t really require C++ knowledge, although that’s certainly helpful – it’s only about refactoring the JS, as the C++ parts should be identical between those two systems…

I’ve removed the label for now.

@inidaname The relevant code is in lib/net.js and lib/internal/http2/core.js. As a start, you might want to just try to make _write look identical for both of these, so that they can be merged into being the same function.

I think we’d want to create a new file internal/ for a resulting new base class, but that doesn’t have to happen right now.

@inidaname
Copy link

@addaleax Okay thank you

@SirR4T
Copy link
Contributor

SirR4T commented Mar 3, 2018

Hi @addaleax : would like to take a shot at this, though would need some beginner help too.

For instance, _write in lib/internal/http2/core.js seems to use LibuvStreamWrap, whereas in lib/internal/net.js, it seems to use fs.write(). Is the intent of this issue to change lib/internal/net.js 's _write to use LibuvStreamWrap instead?

@addaleax
Copy link
Member Author

addaleax commented Mar 3, 2018

would like to take a shot at this

@SirR4T Sure! But maybe take a different bit of the code, unless @inidaname says that they aren’t working on it anymore.

For instance, _write in lib/internal/http2/core.js seems to use LibuvStreamWrap

Well, the underlying stream isn’t a LibuvStreamWrap, it’s an Http2Stream – that shouldn’t matter in practice, because both of these C++ classes use a common interface, which is exposed via the StreamBase class. (Side note: You probably don’t have to modify C++ for this in any way.)

whereas in lib/internal/net.js, it seems to use fs.write().

The code from lib/internal/net.js isn’t what I’m thinking about – it can probably stay as it is.

For net.Socket, the main implementation of _write() and _writev() can be found in lib/net.js and looks a lot more similar to what’s used in lib/internal/http2/core.js.

Is the intent of this issue to change lib/internal/net.js 's _write to use LibuvStreamWrap instead?

There’s quite a few common pieces between lib/net.js and lib/internal/http2.js that just deal with how the StreamBase C++ API is matched to the “normal” Node streams API.

_write() and _writev() are part of that, but there is other code (e.g. onread in lib/net.js and onStreamRead in lib/internal/http2/core.js) that could also be merged. Maybe take a look at that first? It’s going to be trickier than the write functions, but I hope it’s independent enough for that to work.

If that sounds like a lot, or turns out to be too tricky: A first part of this might be getting rid of the _socketEnd event in lib/net.js. It should be possible to figure out in onread whether self.destroy() should be called or not, based on the writable state of the stream, so we don’t need to create an event listener in afterShutdown. I think this is essentially being done in #19241

@inidaname
Copy link

Hello @addaleax
Thank you for the chance but I guess @SirR4T understand the direction been battling with other projects for sometime will be okay if you can take it up
Go for it.

@addaleax
Copy link
Member Author

@SirR4T Are you still interested in this?

@SirR4T
Copy link
Contributor

SirR4T commented Mar 12, 2018

I am, but looks like I may be out of my depth here. Maybe further hints might help? Or I'll try my hand at other issues first.

@addaleax
Copy link
Member Author

@SirR4T I think you could break this down into small pieces, if that helps. And please don’t be shy to approach me with questions if you have any.

For example, once discrepancy here is that net.js uses .destroy() if there was a write error:

node/lib/net.js

Lines 778 to 779 in 22b6804

if (err)
return this.destroy(errnoException(err, 'write', req.error), cb);

Whereas HTTP/2 uses a plain throw:

if (err)
throw errnoException(err, 'write', req.error);

We should probably change http2 to use .destroy() too, because we don’t handle exceptions coming from inside _write() callbacks very well. (There’s another similar instance in the HTTP/2 code.)

Also, it looks like those lines in the HTTP/2 implementation aren’t covered by our tests: https://coverage.nodejs.org/coverage-0048169f5e6d280f/root/internal/http2/core.js.html

Adding a test for them would be a nice change to go along with aligning the implementations, if you feel up for it.

SirR4T added a commit to SirR4T/node that referenced this issue Mar 16, 2018
@SirR4T
Copy link
Contributor

SirR4T commented Mar 16, 2018

Hey @addaleax , I think i got the .destroy() part correct, but I'm still baffled on how to add test cases.

I would think I should induce a situation where createWriteReq() fails, and then assert that indeed stream is destroyed. I attempted to track when would createWriteReq() fail, but I don't see where the C++ side either returns any errno, or throws any exception.

@addaleax
Copy link
Member Author

but I'm still baffled on how to add test cases.

Hm – I guess leave it out then first. I thought you could make this fail by breaking the underlying connection before the write, but a) I missed that HTTP/2 streams are still always asynchronous and b) a broken connection would probably destroy the HTTP/2 stream anyway.

@SirR4T
Copy link
Contributor

SirR4T commented Mar 21, 2018

Hey @addaleax ! what should be the next steps here?

addaleax pushed a commit that referenced this issue Mar 23, 2018
First steps towards #19060

PR-URL: #19389
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
addaleax pushed a commit that referenced this issue Mar 27, 2018
Squashed from:

- lib: separate writev responsibilities from writeGeneric
- lib: fix calling of cb twice
- lib: extract streamId out of stream_base to caller
- lib: add symbols instead of methods to hide impl details
- lib: remove unneeded lines
- lib: use Object.assign instead of apply
- lib: rename mixin StreamBase to StreamSharedMethods
- lib: use stream shared funcs as top level instead of
  properties of prototypes
- lib: mv lib/internal/stream_shared_methods.js
  lib/internal/stream_base_commons.js
- lib: add comment for readability
- lib: refactor _writev in Http2Stream
- lib: rephrase comment
- lib: revert usage of const,let for perf reasons

PR-URL: #19527
Refs: #19060
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Trivikram Kamat <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
addaleax added a commit to addaleax/node that referenced this issue Apr 1, 2018
Merge error handling for `net.Socket`s and `Http2Stream`s,
and align the callback property names as `callback`.

Refs: nodejs#19060
targos pushed a commit that referenced this issue Apr 2, 2018
First steps towards #19060

PR-URL: #19389
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
BridgeAR pushed a commit to BridgeAR/node that referenced this issue May 1, 2018
Squashed from:

- lib: separate writev responsibilities from writeGeneric
- lib: fix calling of cb twice
- lib: extract streamId out of stream_base to caller
- lib: add symbols instead of methods to hide impl details
- lib: remove unneeded lines
- lib: use Object.assign instead of apply
- lib: rename mixin StreamBase to StreamSharedMethods
- lib: use stream shared funcs as top level instead of
  properties of prototypes
- lib: mv lib/internal/stream_shared_methods.js
  lib/internal/stream_base_commons.js
- lib: add comment for readability
- lib: refactor _writev in Http2Stream
- lib: rephrase comment
- lib: revert usage of const,let for perf reasons

PR-URL: nodejs#19527
Refs: nodejs#19060
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Trivikram Kamat <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
BridgeAR pushed a commit to BridgeAR/node that referenced this issue May 1, 2018
Merge error handling for `net.Socket`s and `Http2Stream`s,
and align the callback property names as `callback`.

Refs: nodejs#19060

PR-URL: nodejs#19734
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Tobias Nießen <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Trivikram Kamat <[email protected]>
kjin pushed a commit to kjin/node that referenced this issue May 1, 2018
First steps towards nodejs#19060

PR-URL: nodejs#19389
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
MylesBorins pushed a commit that referenced this issue May 2, 2018
First steps towards #19060

Backport-PR-URL: #20456
PR-URL: #19389
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
MylesBorins pushed a commit that referenced this issue May 15, 2018
First steps towards #19060

Backport-PR-URL: #20456
PR-URL: #19389
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
MylesBorins pushed a commit that referenced this issue May 15, 2018
First steps towards #19060

Backport-PR-URL: #20456
PR-URL: #19389
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
@SirR4T
Copy link
Contributor

SirR4T commented Aug 3, 2018

Hi @addaleax , I was just taking a second look at the onread() and onStreamRead() (in lib/net.js and lib/http2/core) functions. It seems to me that if lib/net.js started adopting more symbols, like [kOwner], [kMaybeDestroy], then maybe a single function could be reused on both net.Socket and Http2Stream objects. Is that the correct direction forward?

@jasnell
Copy link
Member

jasnell commented Aug 10, 2018

Ping @addaleax ... any progress here?

@apapirovski
Copy link
Member

Seems like we had some decent progress here. Not sure there's a ton more we can easily do. I'm going to close out for now but feel free to reopen if you believe I've made a mistake.

@addaleax
Copy link
Member Author

addaleax commented Nov 3, 2018

Not sure there's a ton more we can easily do.

Yeah, I don’t think we’re even halfway where I want to be. 😄 I’ll work more on this bit in the near future.

@addaleax addaleax reopened this Nov 3, 2018
addaleax added a commit to addaleax/node that referenced this issue Nov 15, 2018
danbev pushed a commit that referenced this issue Nov 21, 2018
PR-URL: #24380
Refs: #19060
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Daniel Bevenius <[email protected]>
targos pushed a commit that referenced this issue Nov 21, 2018
PR-URL: #24380
Refs: #19060
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Daniel Bevenius <[email protected]>
@jamesgeorge007
Copy link
Contributor

@addaleax I would like to give it a shot as well 👍
What portion would you like me to take up?

rvagg pushed a commit that referenced this issue Nov 28, 2018
PR-URL: #24380
Refs: #19060
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Daniel Bevenius <[email protected]>
@DamianRivas
Copy link

@addaleax is help needed in closing this issue?

refack pushed a commit to refack/node that referenced this issue Jan 14, 2019
PR-URL: nodejs#24380
Refs: nodejs#19060
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Daniel Bevenius <[email protected]>
addaleax pushed a commit that referenced this issue Jan 27, 2019
PR-URL: #25084
Refs: #19060
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
addaleax pushed a commit that referenced this issue Jan 27, 2019
PR-URL: #25084
Refs: #19060
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
@Ethan-Arrowood
Copy link
Contributor

If there are any outstanding parts you want merged together I'd like to try it out too!

@jagtesh
Copy link

jagtesh commented Feb 9, 2019

I would love to help out as well; I'm comfortable working on both C++ and JS parts.

@BridgeAR
Copy link
Member

BridgeAR commented Jan 4, 2020

@ronag I guess you might be interested in this.

@sachin2605
Copy link

sachin2605 commented Jan 6, 2020 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Issues that need assistance from volunteers or PRs that need help to proceed. http2 Issues or PRs related to the http2 subsystem. net Issues and PRs related to the net subsystem.
Projects
None yet
Development

No branches or pull requests