Skip to content

Commit 8231531

Browse files
authored
Destroy socket when there was an error on it (brianc#1975)
When error happens on socket, potentially dead socket is kept open indefinitely by calling "connection.end()". Similar issue is that it keeps socket open until long-running query is finished even though the connection was ended.
1 parent e404dd5 commit 8231531

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

packages/pg/lib/client.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ Client.prototype.query = function (config, values, callback) {
545545
Client.prototype.end = function (cb) {
546546
this._ending = true
547547

548-
if (this.activeQuery) {
548+
if (this.activeQuery || !this._queryable) {
549549
// if we have an active query we need to force a disconnect
550550
// on the socket - otherwise a hung query could block end forever
551551
this.connection.stream.destroy()

packages/pg/test/integration/connection-pool/error-tests.js

+29
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict'
22
var helper = require('./test-helper')
33
const pg = helper.pg
4+
const native = helper.args.native
45

56
const suite = new helper.Suite()
67
suite.test('connecting to invalid port', (cb) => {
@@ -99,3 +100,31 @@ suite.test('connection-level errors cause future queries to fail', (cb) => {
99100
}))
100101
}))
101102
})
103+
104+
suite.test('handles socket error during pool.query and destroys it immediately', (cb) => {
105+
const pool = new pg.Pool({ max: 1 })
106+
107+
if (native) {
108+
pool.query('SELECT pg_sleep(10)', [], (err) => {
109+
assert.equal(err.message, 'canceling statement due to user request')
110+
cb()
111+
})
112+
113+
setTimeout(() => {
114+
pool._clients[0].native.cancel((err) => {
115+
assert.ifError(err)
116+
})
117+
}, 100)
118+
} else {
119+
pool.query('SELECT pg_sleep(10)', [], (err) => {
120+
assert.equal(err.message, 'network issue')
121+
assert.equal(stream.destroyed, true)
122+
cb()
123+
})
124+
125+
const stream = pool._clients[0].connection.stream
126+
setTimeout(() => {
127+
stream.emit('error', new Error('network issue'))
128+
}, 100)
129+
}
130+
})

0 commit comments

Comments
 (0)