Skip to content

Commit 8874b2e

Browse files
ShogunPandalpinca
authored andcommitted
http: start connections checking interval on listen
Co-authored-by: Luigi Pinca <luigipinca@gmail.com> PR-URL: #48611 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
1 parent cb43717 commit 8874b2e

File tree

4 files changed

+71
-6
lines changed

4 files changed

+71
-6
lines changed

lib/_http_server.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -493,14 +493,16 @@ function storeHTTPOptions(options) {
493493
}
494494
}
495495

496-
function setupConnectionsTracking(server) {
496+
function setupConnectionsTracking() {
497497
// Start connection handling
498-
server[kConnections] = new ConnectionsList();
498+
if (!this[kConnections]) {
499+
this[kConnections] = new ConnectionsList();
500+
}
499501

500502
// This checker is started without checking whether any headersTimeout or requestTimeout is non zero
501503
// otherwise it would not be started if such timeouts are modified after createServer.
502-
server[kConnectionsCheckingInterval] =
503-
setInterval(checkConnections.bind(server), server.connectionsCheckingInterval).unref();
504+
this[kConnectionsCheckingInterval] =
505+
setInterval(checkConnections.bind(this), this.connectionsCheckingInterval).unref();
504506
}
505507

506508
function Server(options, requestListener) {
@@ -533,11 +535,12 @@ function Server(options, requestListener) {
533535
this.httpAllowHalfOpen = false;
534536

535537
this.on('connection', connectionListener);
538+
this.on('listening', setupConnectionsTracking);
536539

537540
this.timeout = 0;
538541
this.maxHeadersCount = null;
539542
this.maxRequestsPerSocket = 0;
540-
setupConnectionsTracking(this);
543+
541544
this[kUniqueHeaders] = parseUniqueHeadersOption(options.uniqueHeaders);
542545
}
543546
ObjectSetPrototypeOf(Server.prototype, net.Server.prototype);
@@ -549,6 +552,10 @@ Server.prototype.close = function() {
549552
};
550553

551554
Server.prototype.closeAllConnections = function() {
555+
if (!this[kConnections]) {
556+
return;
557+
}
558+
552559
const connections = this[kConnections].all();
553560

554561
for (let i = 0, l = connections.length; i < l; i++) {
@@ -557,6 +564,10 @@ Server.prototype.closeAllConnections = function() {
557564
};
558565

559566
Server.prototype.closeIdleConnections = function() {
567+
if (!this[kConnections]) {
568+
return;
569+
}
570+
560571
const connections = this[kConnections].idle();
561572

562573
for (let i = 0, l = connections.length; i < l; i++) {

lib/https.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,9 @@ function Server(opts, requestListener) {
8686

8787
this.timeout = 0;
8888
this.maxHeadersCount = null;
89-
setupConnectionsTracking(this);
89+
this.on('listening', setupConnectionsTracking);
9090
}
91+
9192
ObjectSetPrototypeOf(Server.prototype, tls.Server.prototype);
9293
ObjectSetPrototypeOf(Server, tls.Server);
9394

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
3+
// Flags: --expose-gc
4+
5+
// Check that creating a server without listening does not leak resources.
6+
7+
require('../common');
8+
const onGC = require('../common/ongc');
9+
const Countdown = require('../common/countdown');
10+
11+
const http = require('http');
12+
const max = 100;
13+
14+
// Note that Countdown internally calls common.mustCall, that's why it's not done here.
15+
const countdown = new Countdown(max, () => {});
16+
17+
for (let i = 0; i < max; i++) {
18+
const server = http.createServer((req, res) => {});
19+
onGC(server, { ongc: countdown.dec.bind(countdown) });
20+
}
21+
22+
setImmediate(() => {
23+
global.gc();
24+
});
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
'use strict';
2+
3+
// Flags: --expose-gc
4+
5+
// Check that creating a server without listening does not leak resources.
6+
7+
const common = require('../common');
8+
9+
if (!common.hasCrypto) {
10+
common.skip('missing crypto');
11+
}
12+
13+
const onGC = require('../common/ongc');
14+
const Countdown = require('../common/countdown');
15+
16+
const https = require('https');
17+
const max = 100;
18+
19+
// Note that Countdown internally calls common.mustCall, that's why it's not done here.
20+
const countdown = new Countdown(max, () => {});
21+
22+
for (let i = 0; i < max; i++) {
23+
const server = https.createServer((req, res) => {});
24+
onGC(server, { ongc: countdown.dec.bind(countdown) });
25+
}
26+
27+
setImmediate(() => {
28+
global.gc();
29+
});

0 commit comments

Comments
 (0)