From ad61d77fa358be6759cbf52a370ab2e53a83364c Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Thu, 28 Oct 2010 11:33:33 -0700 Subject: [PATCH] Abstract out net.Server.prototype._rejectPending Does the same timeout action for maxConnections as it does for EMFILE. --- benchmark/idle_server.js | 2 ++ lib/net.js | 61 +++++++++++++++++++++++++++--------------------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/benchmark/idle_server.js b/benchmark/idle_server.js index 53afc77..17d11a1 100644 --- a/benchmark/idle_server.js +++ b/benchmark/idle_server.js @@ -11,6 +11,8 @@ server = net.Server(function (socket) { }); +server.maxConnections = 128; + server.listen(9000); var oldConnections, oldErrors; diff --git a/lib/net.js b/lib/net.js index d7c747d..fcb0750 100644 --- a/lib/net.js +++ b/lib/net.js @@ -959,7 +959,7 @@ function Server (/* [ options, ] listener */) { self.watcher.callback = function () { // Just in case we don't have a dummy fd. getDummyFD(); - + if (self._acceptTimer) { // Somehow the watcher got started again. Need to wait until // the timer finishes. @@ -975,36 +975,17 @@ function Server (/* [ options, ] listener */) { // Gracefully reject pending clients by freeing up a file // descriptor. rescueEMFILE(function() { - var acceptCount = 0; - // 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; - } - } + self._rejectPending(); }); - return; } if (!peerInfo) return; if (self.maxConnections && self.connections >= self.maxConnections) { - // Accept and close the connection. + // Close the connection we just had close(peerInfo.fd); + // Reject all other pending connectins. + self._rejectPending(); 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 // server.listen("/tmp/socket"); // @@ -1122,7 +1129,7 @@ Server.prototype._startWatcher = function () { Server.prototype._doListen = function () { var self = this; - + // Ensure we have a dummy fd for EMFILE conditions. getDummyFD(); @@ -1187,7 +1194,7 @@ function rescueEMFILE(callback) { console.error("(node) Hit max file limit. Increase 'ulimit -n'."); lastEMFILEWarning = now; } - + if (dummyFD) { close(dummyFD); dummyFD = null; @@ -1204,4 +1211,4 @@ function getDummyFD() { dummyFD = null; } } -} \ No newline at end of file +} -- 2.7.4