pool.end() kills connection.query() in promise mode
See original GitHub issueI am working on server that handles several requests asynchronously. Found the problem when close the app gracefully while mysql query is still running. To stop the app, I call pool.end() created by mysql.createPool({}).promise();. But looks like, pool.end() just closes the pool without checking that some connections from the pool are still running. Connection query throws the exception with Error: Pool is closed. Or I do something wrong or inappropriate. Any suggestions?
Exception is:
D:\server\node_modules\mysql2\lib\pool.js:57
return cb(new Error('Pool is closed.'));
^
Error: Pool is closed.
at D:\server\node_modules\mysql2\lib\pool.js:57:21
at PoolConnection.<anonymous> (D:\server\node_modules\mysql2\lib\connection.js:777:13)
at Object.onceWrapper (node:events:628:26)
at PoolConnection.emit (node:events:513:28)
at ClientHandshake.<anonymous> (D:\server\node_modules\mysql2\lib\connection.js:121:14)
at ClientHandshake.emit (node:events:513:28)
at ClientHandshake.execute (D:\server\node_modules\mysql2\lib\commands\command.js:49:10)
at PoolConnection.handlePacket (D:\server\node_modules\mysql2\lib\connection.js:456:32)
at PacketParser.onPacket (D:\server\node_modules\mysql2\lib\connection.js:85:12)
at PacketParser.executeStart (D:\server\node_modules\mysql2\lib\packet_parser.js:75:16)
Node.js v18.12.0
Process finished with exit code 1
Here is simple test to reproduce:
'use strict';
const mysql = require('mysql2');
let pool;
// ---------------------------------------------------------------------
const start = () => {
pool = mysql.createPool({host: 'localhost', user: '', password: ''})
.promise();
}
// ---------------------------------------------------------------------
const stop = () => {
if (pool) {
pool.end();
pool = undefined;
}
}
// ---------------------------------------------------------------------
const query = (sql, params) => {
let connection;
return pool
.getConnection()
.then((conn) => {
connection = conn;
return connection.query(sql, params);
})
.then(([rows, fields]) => {
connection.release();
console.log('Rows', rows, fields);
})
.catch((ex) => {
throw ex;
});
}
// ---------------------------------------------------------------------
// Run
start();
query('SELECT 1');
stop();
My code is bit more sophisticated. I can have several complex queries executing in the pool and some queries waiting in a pool queue. But the root of the problem is the same.
If I wrap stop() in setTimeout() with short delay:
...
setTimeout(() => {
stop();
}, 100)
the test finishes normally with exit code 0.
I am using:
Product | Version |
---|---|
mysql2: | 2.3.3 |
nodejs: | 18.12.0 |
mysql: | 8.0.31 |
OS: | Windows 10 |
Issue Analytics
- State:
- Created 10 months ago
- Comments:12 (6 by maintainers)
I took the liberty to implement the workaround to my issue. Here is my changes in mysql2/promise.js, mysql2/lib/pool.js, and test script repro-exception.js . In this implementation there are no exceptions Error: Pool is closed anymore, and all asynchronous calls of
query()
andstop()
executed as expected. The log of all calls added for debug purposes.Files from mysql2:
Test file:
Kill .txt extra extension when download files. Somehow .js files are not allowed to be dropped in github.
Search for
ADDED:
to see all my changes in 2 mysql2 files.I can make repro.js for this scenario if you like. But the simple test I sent first reproduce the exact problem.