Skip to content

fix(node-http-handler): http2 lets node exit #3541

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

Merged
merged 1 commit into from
Apr 21, 2022

Conversation

simonbuchan
Copy link
Contributor

Description

Http2Session keeps node alive even with no requests running, presumably for server pushed streams. This is a behavior change from node's http 1 Agent, which does not keep node alive when there is no request running.

Emulate that behavior for Node2HttpHandler by unref()ing new sessions, and wrapping requests in a ref() / unref() pair.

This issue is mentioned by #1206, but it incorrectly assumes it's strictly related to connection timeouts. The interaction there is a bit strange to describe, since the actual network connection and request establishment overlap, but the behavior you should see is that if for example, you immediately create and abort a request, the session connection continues, but node will exit as the session is no longer ref()ed. Would be good to explicitly test these weird cases, but that's mostly testing node's http2 module, not the SDK code, and I don't really have that set up.

Testing

Tested by npm linking to a project which was directly using NodeHttp2Handler (for context, I am send sigV4 signed requests to API gateway and AppSync using the SDK signing and request machinery without needing to deal with the SDK service middleware configuration - probably not the cleanest option)

Without this, it hangs if any requests are made. With it, cleanly returns after making a couple requests and reading the response body with streamCollector.

I would be happy to add some unit test code as well, but since neither Http2Session nor the Socket it forwards the ref() / unref() calls to have the hasRef() method, I'm not sure what that would look like. I guess spying on the ref() / unref() calls, and checking they are happening at the right time? Let me know what you think. I don't think there's too much room for issues here, given all the success and error paths already always go through the request close event, so so long as the underlying node request stream gets the abort / close / destroy / goaway message it should always work, but not having anything is not great.


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@simonbuchan simonbuchan requested a review from a team as a code owner April 14, 2022 05:42
@AllanZhengYP AllanZhengYP self-requested a review April 14, 2022 17:31
Copy link
Contributor

@AllanZhengYP AllanZhengYP left a comment

Choose a reason for hiding this comment

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

@simonbuchan Huge thanks for the PR, you cleared the mist. I agree it is pretty hard to test, because we need to validate the programe to exit. So I think it's easier to validate ref() and unref() are called respectively before the request and after the "close" event.

Once this is merged, I can switch Kinesis client to use the H2 handler, and add an integration test with a relatively small jest.timeout().

@simonbuchan
Copy link
Contributor Author

So I think it's easier to validate ref() and unref() are called respectively before the request and after the "close" event.

Do you mean in this PR? I'm happy to give it a try but I'll take any suggestions. It seemed like it would be a bit gory to get the spies right.

Http2Session keeps node alive even with no requests running, presumably
for server pushed streams. This is a behavior change from node's http 1
Agent, which does not keep node alive when there is no request running.

Emulate that behavior by unref()ing new sessions, and wrapping requests
in a ref() / unref() pair.
@simonbuchan
Copy link
Contributor Author

Added some unit tests - might be a bit ugly?

@AllanZhengYP
Copy link
Contributor

The test update looks good, but I need to clean it up a bit. I will merge it and post a follow up PR!

@AllanZhengYP AllanZhengYP merged commit 7480667 into aws:main Apr 21, 2022
keithalpichi pushed a commit to keithalpichi/aws-sdk-js-v3 that referenced this pull request Apr 23, 2022
Http2Session keeps node alive even with no requests running, presumably
for server pushed streams. This is a behavior change from node's http 1
Agent, which does not keep node alive when there is no request running.

Emulate that behavior by unref()ing new sessions, and wrapping requests
in a ref() / unref() pair.
@github-actions
Copy link

github-actions bot commented May 6, 2022

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 6, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants