-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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: set socket timeout when socket connects #8895
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 would think that this would be semver major since it changes the timing?
const http = require('http'); | ||
|
||
const server = http.createServer((req, res) => { | ||
// this space intentionally left blank |
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.
Can you capitalize and punctuate this comment please?
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.
Sure. Done.
@evanlucas yeah semver major or patch depending on if it is considered a bug fix or not. |
832de1e
to
c8a10c7
Compare
@@ -639,7 +639,9 @@ ClientRequest.prototype.setTimeout = function(msecs, callback) { | |||
} | |||
|
|||
this.once('socket', function(sock) { | |||
sock.setTimeout(msecs, emitTimeout); | |||
sock.once('connect', function() { | |||
sock.setTimeout(msecs, emitTimeout); |
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.
nit: This is probably over-micro-optimizing, but using this
instead of sock
inside the callback would avoid allocating a closure every time here.
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 makes sense. Used sock
for readability but happy to fix it.
c8a10c7
to
22a1bbe
Compare
})); | ||
req.on('timeout', common.mustCall(() => req.abort())); | ||
req.on('error', common.mustCall((err) => { | ||
assert.ok(err); |
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 doesn't hurt anything, but you don't really need this assertion since the next one would handle this.
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.
Yeah but if for absurd err
is undefined
it will be a TypeError
(Cannot read property 'message' of undefined) instead of an AssertionError
.
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.
Yea, but it also doesn't really matter.
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.
@cjihrig I think it's easier to grok but I'm fine with removing it.
Edit: done.
22a1bbe
to
2a263a6
Compare
lib/_http_client.js
Outdated
@@ -639,7 +639,9 @@ ClientRequest.prototype.setTimeout = function(msecs, callback) { | |||
} | |||
|
|||
this.once('socket', function(sock) { | |||
sock.setTimeout(msecs, emitTimeout); | |||
sock.once('connect', function() { | |||
this.setTimeout(msecs, emitTimeout); |
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.
in the off chance that someone updates this later to an arrow function, the use of this
internally may be slightly problematic. Perhaps make it more explicit using sock.setTimeout(msec, emitTimeout);
instead?
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.
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.
😄 … yeah, if you want to leave it at sock.setTimeout
for readability, I’m fine with that, too. ;)
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.
Restored sock
.
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.
thank you, I appreciate it.
2a263a6
to
ce555e2
Compare
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.
LGTM
re: semver-patch or semver-major, It's not clear to me either. Let's see what @nodejs/ctc think... |
It might help to know why the old behaviour was bad, and if it was undesirable in all cases? |
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.
Thanks for contributing this! Could you please elaborate on why this is better than the current behavior?
@lpinca thank you for explanation! I see that we have an inconsistency here indeed. I wonder if we should do it in reverse instead and always set timeout without waiting for If we'll go the way it is proposed in this PR, |
@indutny yes it makes sense. I know that some userland modules use an additional timer that is cleared when the Should I open a new PR to always set the timeout without waiting for the |
@lpinca perhaps, let's see what others from @nodejs/http or @nodejs/ctc think? Thanks! |
@indutny I thought again about this and I think it doesn't make sense to change It seems that in all cases (1, 2) The case you are describing is handled by the |
c133999
to
83c7a88
Compare
Closing due to lack of forward progress. We can reopen if necessary |
I think it still makes sense. If we want to keep the current behavior we should at least update the documentation accordingly. |
I am for reopening this. I think it makes sense and I would consider it as a bug fix because it is clearly documented to behave like this PR. |
Fixes a bug that prevented `ClientRequest.prototype.setTimeout()` from working properly when the socket was reused for multiple requests. Fixes: nodejs#16716 Refs: nodejs#8895
Fixes a bug that prevented `ClientRequest.prototype.setTimeout()` from working properly when the socket was reused for multiple requests. Fixes: #16716 Refs: #8895 PR-URL: #16725 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Fixes a bug that prevented `ClientRequest.prototype.setTimeout()` from working properly when the socket was reused for multiple requests. Fixes: nodejs#16716 Refs: nodejs#8895 PR-URL: nodejs#16725 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
PR-URL: nodejs#25121 Refs: nodejs#8895 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
Checklist
make -j8 test
(UNIX), orvcbuild test nosign
(Windows) passesAffected core subsystem(s)
http
Description of change
request.setTimeout()
callssocket.setTimeout()
as soon as a socket is assigned to the request. This makes thetimeout
event to be emitted on the request even if the underlying socket never connects.This commit makes
socket.setTimeout()
to be called only when the underlying socket is connected.