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

http: set socket timeout when socket connects #8895

Closed
wants to merge 1 commit into from

Conversation

lpinca
Copy link
Member

@lpinca lpinca commented Oct 2, 2016

Checklist
  • make -j8 test (UNIX), or vcbuild test nosign (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines
Affected core subsystem(s)

http

Description of change

request.setTimeout() calls socket.setTimeout() as soon as a socket is assigned to the request. This makes the timeout 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.

@nodejs-github-bot nodejs-github-bot added the http Issues or PRs related to the http subsystem. label Oct 2, 2016
@lpinca
Copy link
Member Author

lpinca commented Oct 2, 2016

Copy link
Contributor

@evanlucas evanlucas left a 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
Copy link
Contributor

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?

Copy link
Member Author

@lpinca lpinca Oct 3, 2016

Choose a reason for hiding this comment

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

Sure. Done.

@lpinca
Copy link
Member Author

lpinca commented Oct 3, 2016

@evanlucas yeah semver major or patch depending on if it is considered a bug fix or not.

@lpinca lpinca force-pushed the fix/request-set-timeout branch from 832de1e to c8a10c7 Compare October 3, 2016 11:38
@@ -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);
Copy link
Member

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.

Copy link
Member Author

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.

@lpinca lpinca force-pushed the fix/request-set-timeout branch from c8a10c7 to 22a1bbe Compare October 3, 2016 12:15
}));
req.on('timeout', common.mustCall(() => req.abort()));
req.on('error', common.mustCall((err) => {
assert.ok(err);
Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Contributor

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.

Copy link
Member Author

@lpinca lpinca Oct 3, 2016

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.

@lpinca lpinca force-pushed the fix/request-set-timeout branch from 22a1bbe to 2a263a6 Compare October 3, 2016 13:30
@@ -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);
Copy link
Member

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?

Copy link
Member Author

@lpinca lpinca Oct 6, 2016

Choose a reason for hiding this comment

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

@jasnell read @addaleax's comment above.

Copy link
Member

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. ;)

Copy link
Member Author

Choose a reason for hiding this comment

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

Restored sock.

Copy link
Member

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.

@lpinca lpinca force-pushed the fix/request-set-timeout branch from 2a263a6 to ce555e2 Compare October 6, 2016 18:20
Copy link
Member

@jasnell jasnell left a comment

Choose a reason for hiding this comment

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

LGTM

@jasnell
Copy link
Member

jasnell commented Oct 7, 2016

re: semver-patch or semver-major, It's not clear to me either. Let's see what @nodejs/ctc think...

@addaleax
Copy link
Member

addaleax commented Oct 7, 2016

It might help to know why the old behaviour was bad, and if it was undesirable in all cases?

indutny
indutny previously requested changes Oct 8, 2016
Copy link
Member

@indutny indutny left a 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
Copy link
Member Author

lpinca commented Oct 8, 2016

@indutny I don't know if it's better but

  1. It is consistent with the documentation: "Once a socket is assigned to this request and is connected socket.setTimeout() will be called."
  2. It is consistent with this case?

@indutny
Copy link
Member

indutny commented Oct 8, 2016

@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 connect event?

If we'll go the way it is proposed in this PR, http.request().setTimeout() won't be triggered if socket hasn't connected in a reasonable time. Kernel defaults are usually around 1 minute and this may be too much.

@lpinca
Copy link
Member Author

lpinca commented Oct 8, 2016

@indutny yes it makes sense. I know that some userland modules use an additional timer that is cleared when the response event is emitted to handle cases like the one you are describing.

Should I open a new PR to always set the timeout without waiting for the connect event? If so should this one be closed?

@indutny
Copy link
Member

indutny commented Oct 8, 2016

@lpinca perhaps, let's see what others from @nodejs/http or @nodejs/ctc think?

Thanks!

@lpinca
Copy link
Member Author

lpinca commented Oct 18, 2016

@indutny I thought again about this and I think it doesn't make sense to change request.setTimeout() to make it set the timeout without waiting the connect event.

It seems that in all cases (1, 2) request.setTimeout() explicitly checks if the socket is connected (with the exception of the one this PR deals with) so I guess it's like this by design.

The case you are describing is handled by the timeout option of http.request(). That timeout is forwarded to net.createConnection() without waiting for the socket to be connected.

@rvagg rvagg force-pushed the master branch 2 times, most recently from c133999 to 83c7a88 Compare October 18, 2016 17:02
lpinca referenced this pull request in sindresorhus/timed-out Jan 16, 2017
@jasnell jasnell added the stalled Issues and PRs that are stalled. label Mar 1, 2017
@jasnell
Copy link
Member

jasnell commented Aug 24, 2017

Closing due to lack of forward progress. We can reopen if necessary

@jasnell jasnell closed this Aug 24, 2017
@lpinca
Copy link
Member Author

lpinca commented Aug 25, 2017

I think it still makes sense. If we want to keep the current behavior we should at least update the documentation accordingly.

@BridgeAR
Copy link
Member

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.

@jasnell jasnell reopened this Aug 25, 2017
lpinca added a commit to lpinca/node that referenced this pull request Nov 6, 2017
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
lpinca added a commit that referenced this pull request Nov 6, 2017
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>
cjihrig pushed a commit to cjihrig/node that referenced this pull request Nov 6, 2017
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>
jbunton-atlassian added a commit to jbunton-atlassian/node that referenced this pull request Dec 19, 2018
jbunton-atlassian added a commit to jbunton-atlassian/node that referenced this pull request Dec 19, 2018
jbunton-atlassian added a commit to jbunton-atlassian/node that referenced this pull request Dec 19, 2018
jbunton-atlassian added a commit to jbunton-atlassian/node that referenced this pull request Dec 19, 2018
MylesBorins pushed a commit that referenced this pull request Dec 21, 2018
Refs: #8895

PR-URL: #25123
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
MylesBorins pushed a commit that referenced this pull request Dec 26, 2018
Refs: #8895

PR-URL: #25123
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
vsemozhetbyt pushed a commit that referenced this pull request Jan 9, 2019
PR-URL: #25121
Refs: #8895
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
addaleax pushed a commit that referenced this pull request Jan 14, 2019
PR-URL: #25121
Refs: #8895
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
BridgeAR pushed a commit to BridgeAR/node that referenced this pull request Jan 16, 2019
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>
rvagg pushed a commit that referenced this pull request Feb 28, 2019
Refs: #8895

PR-URL: #25123
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
BethGriggs pushed a commit that referenced this pull request Apr 28, 2019
PR-URL: #25121
Refs: #8895
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
BethGriggs pushed a commit that referenced this pull request May 10, 2019
PR-URL: #25121
Refs: #8895
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
MylesBorins pushed a commit that referenced this pull request May 16, 2019
PR-URL: #25121
Refs: #8895
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
http Issues or PRs related to the http subsystem. semver-major PRs that contain breaking changes and should be released in the next major version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.