-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
http_server: correct order prefinish
=>finish
#3059
Conversation
It is very important to wait for `prefinish` event. It is emitted only when the response becomes active in the pipeline. The ordering of requests/responses in `_http_server.js` is dependent on this, doing it in different order will result in crash. Fix: nodejs#2639
Updated PR, new CI: https://ci.nodejs.org/job/node-test-pull-request/378/ |
if (self._prefinish) | ||
self.emit('finish'); | ||
else | ||
self.on('prefinish', finish); |
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 feel like if this is possible then there's something else wrong with the logic. From the documentation:
After [the finish] event, no more events will be emitted on the response object.
So how could this function ever be called more than once?
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 don't think this changes that logic. This change ensures that the prefinish event is actually emited before the finish event.
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.
Yes. I'm trying to point out that it should be impossible to call this function twice. So the added check shouldn't be necessary.
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.
It is not about calling twice. It is about the order of events. The check handles the case where finish
is emitted before the prefinish
was emitted.
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.
This function is finish()
. I find I confusing that it could be called in the preFinish case.
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.
It is indeed very confusing because we don't use streams API for these events. We should move to them in the future. Feel free to open issue for this, @trevnorris
@indutny: The test case is not exhaustive enough: This test won't ever exit:
output:
And then it'll be stuck. Looks like the second request never receives |
Basically, |
@indutny I guess the modified snippet I posted above is not quite correct, and your patch most likely works. I'll deploy the Node 4.1.1 with your patch on top on our servers and see if the error has gone away. On another note, I'm trying to understand how http responses and pipelining is supposed to work in respect to events fired on the response objects. I also checked the behaviour on 0.10, and I'm more confused than before. When running the following snippet on 0.10 or 4.0: https://gist.github.com/arthurschreiber/f9e11e34adc6e0140867 I see this output:
The documentation for
Isn't this the case for both Does this mean there is no reliable way for determining when a response was sent off in the case that HTTP pipelining is used? |
If the intent is to ensure that |
@indutny I deployed this patch 2 hours ago on multiple layers, and the It looks like this fixes the issue we've been encountering. I believe that 2 different issues have been mixed up in #2639. First:
Second:
This fixes the second issue. According to the comments in #2639, this does not fix the first issue. I believe these two are separate issues with very similar error messages. |
@jasnell this is not related to @arthurschreiber thanks! I'll continue investigating |
|
||
if (id === 1) | ||
server.close(); | ||
}).listen(common.PORT, function() { |
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.
common.mustCall()
?
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.
@Fishrock123 I think this is way too much :) If this is not going to work - we are pretty much in a bad situation. What about verifying the count
instead?
Also, there is a possibly better fix for this: #3068 .
Closing in a favor of #3068 |
It is very important to wait for
prefinish
event.It is emitted only when the response becomes active in the pipeline.
The ordering of requests/responses in
_http_server.js
is dependenton this, doing it in different order will result in crash.
Fix: #2639
cc @nodejs/collaborators @trevnorris @rvagg
This is very important bug fix. We should consider reviewing it very carefully, and merging ASAP (after users will confirm that it fixes stuff for them).