-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Allow for res to have already closed during transmission #4234
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i wasn't able to identify a better way to track this either. this is isolated enough and clear enough that i think it's reasonable 👍
test/transmit.js
Outdated
request.raw.res.once('close', () => close.attend()); | ||
|
||
client.destroy(); // Will trigger abort then close. Prior to node v15.7.0 the res close came | ||
await close.work; // asynchronously after req abort, but since then it comes in the same tick. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
total nit, but the multiline comment to the right here should be above these two lines. as it is, it makes it look like the second line of the comment is regarding the second line of the code which is not the case
There's a fun story here!
In nodejs/citgm#436 it was brought to our attention that node v15.7.0 caused a test to reliably fail in hapi's test suite. I found that the test fails due to the relative timing of request
abort
versus responseclose
timing: prior to node v15.7.0 the response would close in a later tick than the request would abort, and now these occur in the same tick. This means that during hapi's transmission step, where it would typically still assume that the request or response would still have some events to emit (namely, a responseclose
), that there would be no more event fromreq
andres
. The first thing I did was adjust this test to remove the timing discrepancy across node versions, so that it always takes the most aggressive approach that we see occurring in node v15.7.0 (always aborts and closes during marshaling).I searched for a nice node-builtin way to detect this case, but I didn't find anything that stuck. The most promising one was to check for
res.destroyed
, but it turns out that this was set in node v15, but not in node v14. So I decided to add some state to hapi's request that tracks whether the response is closed, which to the best of my knowledge indicates that we can't expect to see any more events fromreq
andres
.I ensured this code path continued to go through hapi's ending routine as though
close
were emitted, even though it ends-up being a no-op. Honestly, adding some more state torequest
to track this and triggering afinish
onres
was not my favorite approach, but it was hard for me to find something more appropriate. Certainly open to suggestions. One aspect that I wouldn't mind some review on is whether the new event listener could introduce some kind of leak since it doesn't stop referencingrequest
as the other listeners do through_eventContext
— I think we're all good there, but it was on my mind. @kanongil of course no pressure, but if you do have time to take a look, I think you are one of the people best-suited to review this area of hapi and any input you have would be appreciated.