-
Notifications
You must be signed in to change notification settings - Fork 468
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Connection Pools continue to attempt to replenish connections after close
is called
#805
Comments
I've created the following test code to try and get as simple a replication as possible (modified from #470): const mssql = require('mssql')
const sqlConfig = {
password: '********',
database: '********',
// connectionTimeout: undefined,
// requestTimeout: 30000,
stream: false,
options: { encrypt: true },
port: 1433,
user: '********',
server: 'localhost',
pool: {
acquireTimeoutMillis: 15000,
},
}
let errorCount = 0;
let pool;
let reconnectTimer;
function connect() {
console.log('trying to connect to server')
mssql.connect(sqlConfig).then((connection) => {
console.log('connection established')
connection.on('error', (e) => {
errorCount++
console.log('Connection errored, trying to close connection', errorCount)
// we have to call `mssql.close` here and not `connection.close`
// because we need the globalConnection to be cleaned up
mssql.close((e) => {
console.log('connection closed')
if (e) {
errorCount++
console.log('connection close error', errorCount)
} else {
// prevent multiple timers being queued
if (reconnectTimer) {
clearTimeout(reconnectTimer)
}
reconnectTimer = setTimeout(connect, 1500)
}
})
})
pool = connection
}).catch((e) => {
errorCount++
console.log('failed to establish connection', errorCount)
// clear the timer so that node can exit
clearInterval(interval)
})
}
function getTime() {
if (!pool) {
console.log('getTime called but no connection is ready')
return
}
pool.request().query('SELECT GETUTCDATE()').then((result) => {
console.log(result)
}).catch((e) => {
errorCount++
console.log('error performing query', errorCount)
})
}
const interval = setInterval(getTime, 5000)
connect() In this example many connection errors are repeatedly emitted even after the Output:
This logging appears to show that an error occurs on the pool. The pool is then closed and the callback fired but connection errors continue to be thrown. Reconnects then appear to be attempted, presumably by the timeout call) until eventually the original the backlog of timers are cleared. |
I think some of the problem here is that the way There doesn't appear to be a way to force the pool to revoke all connections... |
The problem as I can determine it is as follows.
The problem is that there is no kind of back-off or slowdown in attempting to create a new connection resulting in the repeated attempts to create connections that fail if the SQL Server has gone away. Therefore, my suggested fix is that the |
A side issue is that a call to close the pool doesn't abort |
I've looked into this over the past couple of days and my conclusion is that Even after attempting to drain and close the pool new resource create requests will be made, which is far from desirable. There are relevant issues open against generic-pool so hopefully it's a matter of time before it's resolved in the upstream repo. Alternatively we can move to tarn |
This will be fixed in v6 with the move to tarn #808 |
If a connection errors and you attempt to close the pool the pool continues to attempt to re-establish new connections for some time after this.
Please see #470 for previous discussions around this.
Expected behaviour:
The connection pool should abort any pending connection attempts and stop any new attempts from occurring once
connection.close
is called.Actual behaviour:
The connection pool continues to attempt to create connections after
connection.close
has been called.Configuration:
NB: The config doesn't appear to make a difference here
Software versions
The text was updated successfully, but these errors were encountered: