This repository has been archived by the owner on Apr 22, 2023. It is now read-only.
Socket not returning to HTTP agent when exception thrown inside of event leading to backed up http pool #5107
Labels
Comments
To me it looks like this also happens on catched errors, like when a client request timeouts. This seems only to happen on 0.10.1, not on 0.6.19 or 0.8.21. I'll have a look if i can show off the behavior I see with a small test. |
I'll refer you to the documentation for the 'uncaughtException' event:
|
Reopening to address the underlying issue here: we should free the socket before emitting the response.end event, probably, not after.
|
Won't that make it impossible to queue a new request in the 'end' listener that reuses the current connection? |
@bnoordhuis If the net result of this is "Can't reasonably fix without major changes" we can always put it off until 0.12. I just reopened because there is an actual issue here. |
isaacs
added a commit
to isaacs/node-v0.x-archive
that referenced
this issue
Apr 2, 2013
If an http response has an 'end' handler that throws, then the socket will never be released back into the pool. Granted, we do NOT guarantee that throwing will never have adverse effects on Node internal state. Such a guarantee cannot be reasonably made in a shared-global mutable-state side-effecty language like JavaScript. However, in this case, it's a rather trivial patch to increase our resilience a little bit, so it seems like a win. There is no semantic change in this case, except that some event listeners are removed, and the `'free'` event is emitted on nextTick, so that you can schedule another request which will re-use the same socket. From the user's point of view, there should be no detectable difference. Closes nodejs#5107
isaacs
added a commit
that referenced
this issue
Apr 2, 2013
If an http response has an 'end' handler that throws, then the socket will never be released back into the pool. Granted, we do NOT guarantee that throwing will never have adverse effects on Node internal state. Such a guarantee cannot be reasonably made in a shared-global mutable-state side-effecty language like JavaScript. However, in this case, it's a rather trivial patch to increase our resilience a little bit, so it seems like a win. There is no semantic change in this case, except that some event listeners are removed, and the `'free'` event is emitted on nextTick, so that you can schedule another request which will re-use the same socket. From the user's point of view, there should be no detectable difference. Closes #5107
Original issue fixed. |
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
I have found an issue where if there is an exception thrown in the handler of a http response, then this connection will not be returned to the pool until it times out a few minutes later. This causes the pool to backup and can lead to a denial of service attack or other issues in which node will not be able to talk to a host for a given amount of time.
Here is a simple proof of concept:
This code sample will display "started" 10 times and "response" 5 times (maxSockets is 5) then hang for a couple of minutes until those sockets timeout, then show "response" 5 more times.
This exception can be thrown on the response callback or in any of the emit events and will cause a similar issue.
This is especially noticeable when you are running a test framework like mocha and on the response you check the JSON object with an assert which throws an exception and causes the rest of the tests that talk to the same endpoint to fail or timeout.
For example if you have the following type of code
After 5 of these tests fail, the rest will fail with a timeout even though the test might otherwise pass.
The text was updated successfully, but these errors were encountered: