diff --git a/packages/pg-pool/index.js b/packages/pg-pool/index.js index 27875c1f8..3d73fc622 100644 --- a/packages/pg-pool/index.js +++ b/packages/pg-pool/index.js @@ -90,6 +90,7 @@ class Pool extends EventEmitter { this._endCallback = undefined this.ending = false this.ended = false + this.force = false } _isFull() { @@ -102,7 +103,8 @@ class Pool extends EventEmitter { this.log('pulse queue ended') return } - if (this.ending) { + // remove clients from pool if pool is ending and there are no pending queries or if force is enabled + if (this.ending && (!this._pendingQueue.length || this.force)) { this.log('pulse queue on ending') if (this._idle.length) { this._idle.slice().map((item) => { @@ -370,13 +372,19 @@ class Pool extends EventEmitter { return response.result } - end(cb) { + // force (Boolean) and cb (Function) are optional + end(force, cb) { + if (typeof force == 'function') { + cb = force + force = false + } this.log('ending') if (this.ending) { const err = new Error('Called end on pool more than once') return cb ? cb(err) : this.Promise.reject(err) } this.ending = true + this.force = force const promised = promisify(this.Promise, cb) this._endCallback = promised.callback this._pulseQueue() diff --git a/packages/pg-pool/test/ending.js b/packages/pg-pool/test/ending.js index e1839b46c..7aaedca7d 100644 --- a/packages/pg-pool/test/ending.js +++ b/packages/pg-pool/test/ending.js @@ -37,4 +37,24 @@ describe('pool ending', () => { expect(res.rows[0].name).to.equal('brianc') }) ) + + it('pool.end() - finish pending queries by default', async () => { + const pool = new Pool({ poolSize: 10 }) // pool size 10 + let completed = 0 + for (let x = 1; x <= 20; x++) { // queue up 20 queries + pool.query('SELECT $1::text as name', ['brianc']).then(() => completed++) + } + await pool.end() // pool.end() + expect(completed).to.equal(19) // all 20 queries finish (only 19 here because bug #2163 the last query callback hasn't run yet) + }) + + it('pool.end(true) - drop pending queries', async () => { + const pool = new Pool({ poolSize: 10 }) // pool size 10 + let completed = 0 + for (let x = 1; x <= 20; x++) { // queue up 20 queries + pool.query('SELECT $1::text as name', ['brianc']).then(() => completed++) + } + await pool.end(true) // pool.end(true) + expect(completed).to.equal(9) // 10 active queries finish, 10 pending queries get dropped (only 9 here because bug #2163 the last query callback hasn't run yet) + }) })