Skip to content

Commit 776563e

Browse files
committed
Updated connection cleanup process to ensure we cleanup connections that have expired as well as the connections that exceed the config.maxIdle setting
1 parent dee0c08 commit 776563e

File tree

3 files changed

+61
-12
lines changed

3 files changed

+61
-12
lines changed

lib/pool.js

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ class Pool extends EventEmitter {
5353
this._allConnections.length < this.config.connectionLimit
5454
) {
5555
connection = new PoolConnection(this, {
56-
config: this.config.connectionConfig
56+
config: this.config.connectionConfig,
5757
});
5858
this._allConnections.push(connection);
59-
return connection.connect(err => {
59+
return connection.connect((err) => {
6060
if (this._closed) {
6161
return cb(new Error('Pool is closed.'));
6262
}
@@ -102,7 +102,7 @@ class Pool extends EventEmitter {
102102
this._closed = true;
103103
clearTimeout(this._removeIdleTimeoutConnectionsTimer);
104104
if (typeof cb !== 'function') {
105-
cb = function(err) {
105+
cb = function (err) {
106106
if (err) {
107107
throw err;
108108
}
@@ -111,7 +111,7 @@ class Pool extends EventEmitter {
111111
let calledBack = false;
112112
let closedConnections = 0;
113113
let connection;
114-
const endCB = function(err) {
114+
const endCB = function (err) {
115115
if (calledBack) {
116116
return;
117117
}
@@ -136,10 +136,11 @@ class Pool extends EventEmitter {
136136
sql,
137137
values,
138138
cb,
139-
this.config.connectionConfig
139+
this.config.connectionConfig,
140140
);
141141
if (typeof cmdQuery.namedPlaceholders === 'undefined') {
142-
cmdQuery.namedPlaceholders = this.config.connectionConfig.namedPlaceholders;
142+
cmdQuery.namedPlaceholders =
143+
this.config.connectionConfig.namedPlaceholders;
143144
}
144145
this.getConnection((err, conn) => {
145146
if (err) {
@@ -200,9 +201,10 @@ class Pool extends EventEmitter {
200201
this._removeIdleTimeoutConnectionsTimer = setTimeout(() => {
201202
try {
202203
while (
203-
this._freeConnections.length > this.config.maxIdle &&
204-
Date.now() - this._freeConnections.get(0).lastActiveTime >
205-
this.config.idleTimeout
204+
this._freeConnections.length > this.config.maxIdle ||
205+
(this._freeConnections.length > 0 &&
206+
Date.now() - this._freeConnections.get(0).lastActiveTime >
207+
this.config.idleTimeout)
206208
) {
207209
this._freeConnections.get(0).destroy();
208210
}
@@ -217,15 +219,15 @@ class Pool extends EventEmitter {
217219
sql,
218220
values,
219221
this.config.connectionConfig.stringifyObjects,
220-
this.config.connectionConfig.timezone
222+
this.config.connectionConfig.timezone,
221223
);
222224
}
223225

224226
escape(value) {
225227
return mysql.escape(
226228
value,
227229
this.config.connectionConfig.stringifyObjects,
228-
this.config.connectionConfig.timezone
230+
this.config.connectionConfig.timezone,
229231
);
230232
}
231233

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
'use strict';
2+
3+
const createPool = require('../common.test.cjs').createPool;
4+
const { assert } = require('poku');
5+
6+
const pool = new createPool({
7+
connectionLimit: 3, // 5 connections
8+
maxIdle: 1, // 1 idle connection
9+
idleTimeout: 5000, // 5 seconds
10+
});
11+
12+
pool.getConnection((err1, connection1) => {
13+
assert.ifError(err1);
14+
assert.ok(connection1);
15+
pool.getConnection((err2, connection2) => {
16+
assert.ifError(err2);
17+
assert.ok(connection2);
18+
assert.notStrictEqual(connection1, connection2);
19+
pool.getConnection((err3, connection3) => {
20+
assert.ifError(err3);
21+
assert.ok(connection3);
22+
assert.notStrictEqual(connection1, connection3);
23+
assert.notStrictEqual(connection2, connection3);
24+
connection1.release();
25+
connection2.release();
26+
connection3.release();
27+
assert(pool._allConnections.length === 3);
28+
assert(pool._freeConnections.length === 3);
29+
setTimeout(() => {
30+
// After 5000ms, all connections should be considered idle and removed
31+
assert(pool._allConnections.length === 0);
32+
assert(pool._freeConnections.length === 0);
33+
pool.getConnection((err4, connection4) => {
34+
assert.ifError(err4);
35+
assert.ok(connection4);
36+
assert(pool._allConnections.length === 1);
37+
assert(pool._freeConnections.length === 0);
38+
connection4.release();
39+
connection4.destroy();
40+
pool.end();
41+
});
42+
}, 7000);
43+
});
44+
});
45+
});

test/integration/test-pool-release-idle-connection.test.cjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ pool.getConnection((err1, connection1) => {
3939
connection4.destroy();
4040
pool.end();
4141
});
42-
}, 7000);
42+
// Setting the time to a lower value than idleTimeout will ensure that the connection is not considered idle
43+
// during our assertions
44+
}, 4000);
4345
});
4446
});
4547
});

0 commit comments

Comments
 (0)