Skip to content

Commit c9da2c0

Browse files
committed
http: check for number of open connections during drain
If connections reach 0, we close earlier.
1 parent ef66d52 commit c9da2c0

File tree

1 file changed

+24
-3
lines changed

1 file changed

+24
-3
lines changed

lib/_http_server.js

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,7 @@ function Server(options, requestListener) {
598598

599599
this.drainStarted = false;
600600
this.drainTimeout = options.drainTimeout || 0;
601+
this.drainConnectionsPollInterval = options.drainConnectionsPollInterval || 500;
601602

602603
if (requestListener) {
603604
// Do we want to gracefully drain existing keep-alive connections
@@ -662,7 +663,9 @@ Server.prototype.closeIdleConnections = function closeIdleConnections(callback)
662663
if (!this[kConnections]) {
663664
return;
664665
}
666+
665667
const fn = () => {
668+
// Destroy all still remaining idle connections.
666669
const connections = this[kConnections].idle();
667670
for (let i = 0, l = connections.length; i < l; i++) {
668671
if (connections[i].socket._httpMessage && !connections[i].socket._httpMessage.finished) {
@@ -673,10 +676,28 @@ Server.prototype.closeIdleConnections = function closeIdleConnections(callback)
673676
if (typeof callback === 'function') {
674677
callback();
675678
}
679+
}
680+
681+
// For graceful draining, if drainTimeout > 0 (see below)
682+
let startTime = Date.now()
683+
let timer = null;
684+
let graceIterations = 3;
685+
const checkFn = () => {
686+
const connections = this[kConnections].all();
687+
if (Date.now() - startTime > this.drainTimeout || (connections.length === 0 && graceIterations-- <= 0)) {
688+
// Either drain period has ended, or we have no open connections anymore.
689+
// We can close now.
690+
clearInterval(timer);
691+
timer = null;
692+
fn();
693+
}
676694
};
677-
this.drainStarted = true;
678-
if (this.drainTimeout > 0) {
679-
setTimeout(() => { fn() }, this.drainTimeout);
695+
696+
if (this.drainTimeout > 0 && !this.drainStarted) {
697+
this.drainStarted = true;
698+
// Start polling for idle connections.
699+
// If all connections are gone or drain period ends, we call the callback.
700+
timer = setInterval(checkFn, this.drainConnectionsPollInterval);
680701
} else {
681702
fn();
682703
}

0 commit comments

Comments
 (0)