Abstract out net.Server.prototype._rejectPending
Does the same timeout action for maxConnections as it does for EMFILE.
This commit is contained in:
parent
74d0a077ec
commit
ad61d77fa3
@ -11,6 +11,8 @@ server = net.Server(function (socket) {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server.maxConnections = 128;
|
||||||
|
|
||||||
server.listen(9000);
|
server.listen(9000);
|
||||||
|
|
||||||
var oldConnections, oldErrors;
|
var oldConnections, oldErrors;
|
||||||
|
61
lib/net.js
61
lib/net.js
@ -959,7 +959,7 @@ function Server (/* [ options, ] listener */) {
|
|||||||
self.watcher.callback = function () {
|
self.watcher.callback = function () {
|
||||||
// Just in case we don't have a dummy fd.
|
// Just in case we don't have a dummy fd.
|
||||||
getDummyFD();
|
getDummyFD();
|
||||||
|
|
||||||
if (self._acceptTimer) {
|
if (self._acceptTimer) {
|
||||||
// Somehow the watcher got started again. Need to wait until
|
// Somehow the watcher got started again. Need to wait until
|
||||||
// the timer finishes.
|
// the timer finishes.
|
||||||
@ -975,36 +975,17 @@ function Server (/* [ options, ] listener */) {
|
|||||||
// Gracefully reject pending clients by freeing up a file
|
// Gracefully reject pending clients by freeing up a file
|
||||||
// descriptor.
|
// descriptor.
|
||||||
rescueEMFILE(function() {
|
rescueEMFILE(function() {
|
||||||
var acceptCount = 0;
|
self._rejectPending();
|
||||||
// Accept and close the waiting clients one at a time.
|
|
||||||
// Single threaded programming ftw.
|
|
||||||
while (true) {
|
|
||||||
peerInfo = accept(self.fd);
|
|
||||||
if (!peerInfo) break;
|
|
||||||
close(peerInfo.fd);
|
|
||||||
|
|
||||||
// Don't become DoS'd by incoming requests
|
|
||||||
if (++acceptCount > 50) {
|
|
||||||
assert(!self._acceptTimer);
|
|
||||||
self.watcher.stop();
|
|
||||||
// Wait a second before accepting more.
|
|
||||||
self._acceptTimer = setTimeout(function () {
|
|
||||||
assert(parseInt(self.fd) >= 0);
|
|
||||||
self._acceptTimer = null;
|
|
||||||
self.watcher.start();
|
|
||||||
}, 1000);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!peerInfo) return;
|
if (!peerInfo) return;
|
||||||
|
|
||||||
if (self.maxConnections && self.connections >= self.maxConnections) {
|
if (self.maxConnections && self.connections >= self.maxConnections) {
|
||||||
// Accept and close the connection.
|
// Close the connection we just had
|
||||||
close(peerInfo.fd);
|
close(peerInfo.fd);
|
||||||
|
// Reject all other pending connectins.
|
||||||
|
self._rejectPending();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1041,6 +1022,32 @@ exports.createServer = function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Server.prototype._rejectPending = function () {
|
||||||
|
var self = this;
|
||||||
|
var acceptCount = 0;
|
||||||
|
// Accept and close the waiting clients one at a time.
|
||||||
|
// Single threaded programming ftw.
|
||||||
|
while (true) {
|
||||||
|
peerInfo = accept(this.fd);
|
||||||
|
if (!peerInfo) return;
|
||||||
|
close(peerInfo.fd);
|
||||||
|
|
||||||
|
// Don't become DoS'd by incoming requests
|
||||||
|
if (++acceptCount > 50) {
|
||||||
|
assert(!this._acceptTimer);
|
||||||
|
this.watcher.stop();
|
||||||
|
// Wait a second before accepting more.
|
||||||
|
this._acceptTimer = setTimeout(function () {
|
||||||
|
assert(parseInt(self.fd) >= 0);
|
||||||
|
self._acceptTimer = null;
|
||||||
|
self.watcher.start();
|
||||||
|
}, 1000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Listen on a UNIX socket
|
// Listen on a UNIX socket
|
||||||
// server.listen("/tmp/socket");
|
// server.listen("/tmp/socket");
|
||||||
//
|
//
|
||||||
@ -1122,7 +1129,7 @@ Server.prototype._startWatcher = function () {
|
|||||||
|
|
||||||
Server.prototype._doListen = function () {
|
Server.prototype._doListen = function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
// Ensure we have a dummy fd for EMFILE conditions.
|
// Ensure we have a dummy fd for EMFILE conditions.
|
||||||
getDummyFD();
|
getDummyFD();
|
||||||
|
|
||||||
@ -1187,7 +1194,7 @@ function rescueEMFILE(callback) {
|
|||||||
console.error("(node) Hit max file limit. Increase 'ulimit -n'.");
|
console.error("(node) Hit max file limit. Increase 'ulimit -n'.");
|
||||||
lastEMFILEWarning = now;
|
lastEMFILEWarning = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dummyFD) {
|
if (dummyFD) {
|
||||||
close(dummyFD);
|
close(dummyFD);
|
||||||
dummyFD = null;
|
dummyFD = null;
|
||||||
@ -1204,4 +1211,4 @@ function getDummyFD() {
|
|||||||
dummyFD = null;
|
dummyFD = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user