-
Notifications
You must be signed in to change notification settings - Fork 30k
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: make request.abort()
destroy the socket
#10818
Conversation
const net = require('net'); | ||
|
||
const server = http.createServer(() => { | ||
throw new Error('test invalidation'); |
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 use common.fail()
instead of explicitly throwing (in the other test 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.
I originally used common.fail()
but I honestly don't like to use it with a non string argument.
In this case it will be called with the request
object and the error message will be something like AssertionError: [object Object]
. I find it horrible.
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.fail()
takes an optional string argument.
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 are you suggesting to use this?
http.createServer(() => common.fail('whatever'));
I thought you wanted to pass it directly to http.createServer()
http.createServer(common.fail);
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'd be OK with either. If you like the first one, go with that.
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.
Even if I don't like http.createServer(common.fail);
, for the reason stated above, I changed it to that for consistency as there are other tests which use the same pattern.
socket.destroy(); | ||
} else { | ||
socket.emit('free'); | ||
} |
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'm not even sure if it's appropriate to emit 'free' and skip destroying the socket. ClientRequest#abort()
always calls socket.destroy()
when there is one.
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.
@bnoordhuis I think this is for keep-alive sockets?
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.
@bnoordhuis I guess you were referring to
Lines 296 to 299 in 77be180
if (this.socket) { | |
// in-progress | |
this.socket.destroy(); | |
} |
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 is when socket.emit('free');
was added: d0c7d93#diff-e3bc37430eb078ccbafe3aa3b570c91a, previously the socket was destroyed 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.
I think we should always destroy()
, I do not see a way for this socket to be reused even if there is an agent.
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.
Agree. There's really no safe way to reuse it. destroy()
is the safest thing to do
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've added a test which should clarify why socket.emit('free')
is used. It's for queued requests which are already aborted.
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.
See f52c874b737ccb7e92d640b31e02c6efb3acd22c.
Is there anything I can do to move this forward? |
@lpinca Did you find an answer to https://github.com/nodejs/node/pull/10818/files#r96164070? |
@bnoordhuis yeah, this commit d0c7d93#diff-e3bc37430eb078ccbafe3aa3b570c91a
|
The original PR doesn't seem to give more info: nodejs/node-v0.x-archive#7533 |
Also pinging other @nodejs/collaborators. |
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 with some trepidation. Good job on the test coverage though.
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. CITGM should be checked as well
I think CITGM failures (express and spdy) are not related to this change as I can also reproduce them with current master. browserify also failed in other CITGM runs. |
The browserify failure is a module issue (nodejs/citgm#335), not sure about express and spdy. There's also a failure on ember-cli: https://ci.nodejs.org/view/Node.js-citgm/job/citgm-smoker/546/nodes=ppcle-ubuntu1404/testReport/(root)/citgm/ember_cli_v2_11_0/ |
Yup but it doesn't seem to use |
I've started one more CITGM run against master to see if it fails with express and spdy. If not I'll rebase this and run again. |
There seem to be quite a bit of failures with master https://ci.nodejs.org/view/Node.js-citgm/job/citgm-smoker/547. I'll wait a bit before rerunning against this PR. |
f52c874
to
11648e0
Compare
#10558 is responsible for CITGM failures with express and spdy, so I've rebased this before #10558 was landed and re-ran CI: https://ci.nodejs.org/job/node-test-pull-request/6079/ There is one CITGM suspicious failure on ppcle-ubuntu1404 with spdy but I think it is not related as the failing test fails for spdy/3.1 but not for h2 and spdy/3. On top of this the test seems to not use |
@lpinca LGTM. I'm not 100% sure we should backport this to the LTS releases, but that's another discussion. |
It's a bug-fix and I hope we can backport this. It's needed for |
If there are no objections I'll land this tomorrow. |
const req = http.get({agent, port}, common.fail); | ||
req.abort(); | ||
|
||
http.get({agent, port}, (res) => { |
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.
As we have an assertion within this, I would wrap this in 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.
I didn't add it as the test will fail for timeout if the function is not called but will add it if desired.
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.
@thefourtheye done.
bab407d
to
b0ac117
Compare
`request.abort()` did not destroy the socket if it was called before a socket was assigned to the request and the request did not use an `Agent` or a Unix Domain Socket was used. Fixes: nodejs#10812 PR-URL: nodejs#10818 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
b0ac117
to
18d4ee9
Compare
Landed in 18d4ee9. |
`request.abort()` did not destroy the socket if it was called before a socket was assigned to the request and the request did not use an `Agent` or a Unix Domain Socket was used. Fixes: #10812 PR-URL: #10818 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
The tests fail with timeouts on v4.x. Will need a backport PR to land there. |
`request.abort()` did not destroy the socket if it was called before a socket was assigned to the request and the request did not use an `Agent` or a Unix Domain Socket was used. Fixes: #10812 PR-URL: #10818 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
`request.abort()` did not destroy the socket if it was called before a socket was assigned to the request and the request did not use an `Agent` or a Unix Domain Socket was used. Fixes: #10812 PR-URL: #10818 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
`request.abort()` did not destroy the socket if it was called before a socket was assigned to the request and the request did not use an `Agent` or a Unix Domain Socket was used. Fixes: #10812 PR-URL: #10818 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
`request.abort()` did not destroy the socket if it was called before a socket was assigned to the request and the request did not use an `Agent` or a Unix Domain Socket was used. Fixes: #10812 PR-URL: #10818 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
`request.abort()` did not destroy the socket if it was called before a socket was assigned to the request and the request did not use an `Agent` or a Unix Domain Socket was used. Fixes: nodejs/node#10812 PR-URL: nodejs/node#10818 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
request.abort()
did not destroy the socket if it was calledbefore a socket was assigned to the request and the request
did not use an
Agent
or a Unix Domain Socket was used.Fixes: #10812
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
http