Do not spin on aceept() with EMFILE
When a server hit EMFILE it would continue to try to accept new connections from the queue. This patch introduces a timeout of one second where it will stop trying to accept new files. After the second is over it tries again. This is a rather serious bug that has been effecting many highly concurrent programs. It was introduced in 4593c0, version v0.2.0. TODO: A test for this situation. Currently I test it like this termA% cd projects/node termA% ulimit -n 256 termA% ./node benchmark/idle_server.js termB% cd projects/node termB% ./node benchmark/idle_clients.js And watch how the server process behaves.
This commit is contained in:
parent
9bf2975f78
commit
0ac2ef924f
1
TODO
1
TODO
@ -25,3 +25,4 @@
|
||||
based on size but rather read until EOF into a chain of buffers, then
|
||||
concat them together.
|
||||
- process object should be defined in src/node.js not in c++
|
||||
- Test for EMFILE accept spin bug.
|
||||
|
24
lib/net.js
24
lib/net.js
@ -1049,6 +1049,25 @@ function Server (listener) {
|
||||
|
||||
self.connections = 0;
|
||||
|
||||
self.paused = false;
|
||||
self.pauseTimeout = 1000;
|
||||
|
||||
function pause () {
|
||||
// We've hit the maximum file limit. What to do?
|
||||
// Let's try again in 1 second.
|
||||
self.watcher.stop();
|
||||
|
||||
// If we're already paused, don't do another timeout.
|
||||
if (self.paused) return;
|
||||
|
||||
setTimeout(function () {
|
||||
self.paused = false;
|
||||
// Make sure we haven't closed in the interim
|
||||
if (typeof self.fd != 'number') return;
|
||||
self.watcher.start();
|
||||
}, self.pauseTimeout);
|
||||
}
|
||||
|
||||
self.watcher = new IOWatcher();
|
||||
self.watcher.host = self;
|
||||
self.watcher.callback = function () {
|
||||
@ -1056,7 +1075,10 @@ function Server (listener) {
|
||||
try {
|
||||
var peerInfo = accept(self.fd);
|
||||
} catch (e) {
|
||||
if (e.errno == EMFILE) return;
|
||||
if (e.errno == EMFILE) {
|
||||
pause();
|
||||
return;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
if (!peerInfo) return;
|
||||
|
Loading…
x
Reference in New Issue
Block a user