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

Allow for res to have already closed during transmission #4234

Merged
merged 2 commits into from
Mar 16, 2021

Conversation

devinivy
Copy link
Member

@devinivy devinivy commented Mar 3, 2021

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 response close 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 response close), that there would be no more event from req and res. 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 from req and res.

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 to request to track this and triggering a finish on res 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 referencing request 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.

@devinivy devinivy added the bug Bug or defect label Mar 3, 2021
Copy link
Member

@nlf nlf left a 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.
Copy link
Member

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

test/transmit.js Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bug or defect
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants