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

http2: implement ref() and unref() on sessions #17620

Closed
wants to merge 6 commits into from

Conversation

kjin
Copy link
Contributor

@kjin kjin commented Dec 11, 2017

Fixes #16617

This is my stab at adding ref and unref on ClientHttp2Session instances. It seems mostly straightforward, but there were a few questions I had in mind about this code change:

  • Should ClientHttp2Session instances be unrefd by default?
  • Should these be available on ServerHttp2Session objects as well? (my thought is no)
  • Should calling ref/unref be a no-op after the session has been destroyed, or could it return an error?

I saw this comment made by @addaleax about uv_prepare_t, but I don't really understand it. To me, this code change seems sufficient, but maybe I'm missing something.

Also, I updated the docs to separate ClientHttp2Session from Http2Session... which seemed to make sense considering that this distinction is present even in the codebase.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

http2

@nodejs-github-bot nodejs-github-bot added dont-land-on-v4.x http2 Issues or PRs related to the http2 subsystem. labels Dec 11, 2017
Copy link
Member

@addaleax addaleax left a comment

Choose a reason for hiding this comment

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

I saw this comment made by @addaleax about uv_prepare_t, but I don't really understand it. To me, this code change seems sufficient, but maybe I'm missing something.

The code has changed since then. :)

Should ClientHttp2Session instances be unrefd by default?

I don’t think so; if you have an active network connection, you usually want that to keep the event loop alive.

Should these be available on ServerHttp2Session objects as well? (my thought is no)

Why not? :)

Should calling ref/unref be a no-op after the session has been destroyed, or could it return an error?

It seems doing nothing is what net.Socket does, so I’d go with that? I think that’s what this code already does, right? 👍

doc/api/http2.md Outdated

#### clienthttp2session.unref()
<!-- YAML
added: ??? (TODO)
Copy link
Member

Choose a reason for hiding this comment

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

Can you use added: REPLACEME here? That way it gets picked up automatically by the release tooling :)

@@ -1086,6 +1086,18 @@ class ClientHttp2Session extends Http2Session {
}
return stream;
}

ref() {
if (this[kSocket]) {
Copy link
Member

Choose a reason for hiding this comment

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

Can you also check whether typeof this[kSocket].ref === 'function'? HTTP/2 supports any stream as the underlying socket, so .ref might not be present at that point.

The test file that checks that is test/parallel/test-http2-generic-streams.js, if you want to extend that – I think calling .ref() there would crash right now?

@kjin
Copy link
Contributor Author

kjin commented Dec 12, 2017

Should these be available on ServerHttp2Session objects as well? (my thought is no)

Why not? :)

I thought http.Server instances didn't have them, but I now see that they inherit ref and unref from net.Server. I suppose I couldn't think of use cases for unrefing an http.Server earlier, but there's no reason now to not include them on Http2Session.

Seems like it's worthwhile to ensure unref works on Http2Server as well, so doing both now.

@addaleax
Copy link
Member

@kjin I think those are different things – ServerHttp2Session corresponds to a single connection, Http2Server to the entire server, right? I’m not sure but they probably both have ref/unref methods?

@kjin
Copy link
Contributor Author

kjin commented Dec 12, 2017

Yep, I understand that ServerHttp2Session objects are created on a per-connection basis by an Http2Server instance, and isn't really an analogue of http.Server. I definitely skipped an explanation step there but what I was intending to say was "no reason why http2 server-side objects shouldn't also have ref and unref".

Currently ServerHttp2Session doesn't have unref, but Http2Server does. I think the latter doesn't do anything, and what I was saying above was that I might as well fix that now (whatever that entails). (edit: it actually does work)

@kjin kjin force-pushed the http2-client-session-ref branch 2 times, most recently from 826acba to 8714f6f Compare December 12, 2017 19:28
@kjin
Copy link
Contributor Author

kjin commented Dec 12, 2017

@addaleax Thanks for the feedback so far, I've updated the PR to make ref and unref properties of Http2Session instead of ClientHttp2Session (and the docs accordingly). I kept the docs for ClientHttp2Session#request separate for the same reason as in the initial PR description. Can you take another look when you have the chance?

@kjin kjin changed the title http2: implement ref() and unref() on client sessions http2: implement ref() and unref() on sessions Dec 12, 2017
@jasnell
Copy link
Member

jasnell commented Dec 12, 2017

This should wait to land until after #17406, as is may need to be updated based on those changes.

@TimothyGu
Copy link
Member

@addaleax

Should ClientHttp2Session instances be unrefd by default?

I don’t think so; if you have an active network connection, you usually want that to keep the event loop alive.

Hmm, but if the session isn't transporting any data (just kept open because of HTTP/2 semantics) I don't see a good reason why it should keep the event loop alive.

ref() {
if (this[kSocket]) {
assert(this[kSocket]._handle);
if (typeof this[kSocket]._handle.ref === 'function') {
Copy link
Member

Choose a reason for hiding this comment

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

Why not just this[kSocket].ref? That’s what’s being called anyway, right?

Copy link
Contributor Author

@kjin kjin Dec 13, 2017

Choose a reason for hiding this comment

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

For generic duplex streams this[kSocket] is a JSStreamWrap object, which doesn't have a handle.ref field.

Actually, this makes me think that net.Socket itself should be checking that _handle.ref is a function, rather than here. I'll add a trailing commit that does so, we can drop it if there is already a good rationale for not checking in net.

@addaleax
Copy link
Member

@TimothyGu This is just calling through to the underlying socket, the HTTP2 session itself won’t keep anything open

@kjin
Copy link
Contributor Author

kjin commented Dec 20, 2017

@jasnell @addaleax I've rebased the PR on master. The only conflict was in the docs, since I moved http2session.request to a new ClientHttp2Session section. The rebased commits should reflect whatever changed in the docs since I first opened this PR.

I can understand if it's not in the scope of this PR to move the request docs, but I still think it makes sense considering that ClientHttp2Session is treated as a separate class in http2/core.js.

@jasnell
Copy link
Member

jasnell commented Dec 22, 2017

@addaleax addaleax added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Dec 27, 2017
jasnell pushed a commit that referenced this pull request Dec 28, 2017
PR-URL: #17620
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@jasnell
Copy link
Member

jasnell commented Dec 28, 2017

landed in 120ea9b

@jasnell jasnell closed this Dec 28, 2017
@addaleax addaleax removed the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Dec 29, 2017
MylesBorins pushed a commit to jasnell/node that referenced this pull request Jan 9, 2018
PR-URL: nodejs#17620
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
MylesBorins pushed a commit that referenced this pull request Jan 9, 2018
Backport-PR-URL: #18050
PR-URL: #17620
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@MylesBorins MylesBorins mentioned this pull request Jan 10, 2018
MylesBorins pushed a commit that referenced this pull request Jan 10, 2018
Backport-PR-URL: #18050
PR-URL: #17620
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@ofrobots
Copy link
Contributor

@gibfahn This still needs to be released on 8.x. Let myself or @kjin know if there is any work needed from our side to make that happen.

@gibfahn
Copy link
Member

gibfahn commented Apr 12, 2018

Thanks for the ping, not sure why this hasn't been backported yet.

@kjin
Copy link
Contributor Author

kjin commented Apr 12, 2018

@gibfahn This PR was originally contingent on #17406 landing, so I assume that the backport will be as well.

kjin added a commit to kjin/node that referenced this pull request May 1, 2018
Backport-PR-URL: nodejs#18050
PR-URL: nodejs#17620
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
MylesBorins pushed a commit that referenced this pull request May 2, 2018
Backport-PR-URL: #18050
Backport-PR-URL: #20456
PR-URL: #17620
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@MylesBorins MylesBorins mentioned this pull request May 2, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
http2 Issues or PRs related to the http2 subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

http2: implement ref() and unref() on client sessions
7 participants