Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 8206f7a

Browse files
author
maxbronnikov10
committed
fix: Connection timeout handling for native clients in connected state
Now, when using the native client with a connection timeout, the pool could incorrectly destroy or end a client that was already connected, due to not distinguishing between connection states. This caused issues such as brianc/node-pg-native#49, where a native client that had already established a connection could be forcefully closed if the connection callback was delayed past the timeout.
1 parent fab87b2 commit 8206f7a

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

‎packages/pg-pool/index.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,16 @@ class Pool extends EventEmitter {
241241
let timeoutHit = false
242242
if (this.options.connectionTimeoutMillis) {
243243
tid = setTimeout(() => {
244-
this.log('ending client due to timeout')
245-
timeoutHit = true
246-
// force kill the node driver, and let libpq do its teardown
247-
client.connection ? client.connection.stream.destroy() : client.end()
244+
if (client.connection) {
245+
this.log('ending client due to timeout')
246+
timeoutHit = true
247+
client.connection.stream.destroy()
248+
} else if (!client.isConnected()) {
249+
this.log('ending client due to timeout')
250+
timeoutHit = true
251+
// force kill the node driver, and let libpq do its teardown
252+
client.end()
253+
}
248254
}, this.options.connectionTimeoutMillis)
249255
}
250256

‎packages/pg-pool/test/connection-timeout.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,4 +226,25 @@ describe('connection timeout', () => {
226226
})
227227
})
228228
})
229+
230+
it('should connect if timeout is passed, but native client in connected state', (done) => {
231+
const Client = require('pg').native.Client
232+
233+
Client.prototype.connect = function (cb) {
234+
this._connected = true
235+
236+
return setTimeout(() => {
237+
cb()
238+
}, 200)
239+
}
240+
241+
const pool = new Pool({ connectionTimeoutMillis: 100, port: this.port, host: 'localhost' }, Client)
242+
243+
pool.connect((err, client, release) => {
244+
expect(err).to.be(undefined)
245+
expect(client).to.not.be(undefined)
246+
expect(client.isConnected()).to.be(true)
247+
done()
248+
})
249+
})
229250
})

‎packages/pg/lib/native/client.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,10 @@ Client.prototype.end = function (cb) {
250250
cb = (err) => (err ? reject(err) : resolve())
251251
})
252252
}
253+
253254
this.native.end(function () {
255+
self._connected = false
256+
254257
self._errorAllQueries(new Error('Connection terminated'))
255258

256259
process.nextTick(() => {
@@ -306,3 +309,7 @@ Client.prototype.setTypeParser = function (oid, format, parseFn) {
306309
Client.prototype.getTypeParser = function (oid, format) {
307310
return this._types.getTypeParser(oid, format)
308311
}
312+
313+
Client.prototype.isConnected = function () {
314+
return this._connected
315+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /