From 33e0f164f71b365df3e1d9308ddc510ea38fcc22 Mon Sep 17 00:00:00 2001
From: Asadbek Raimov <asadbekraimov642@gmail.com>
Date: Wed, 12 Jun 2024 02:09:37 +0500
Subject: [PATCH 1/6] Pass callback to clien.end

---
 packages/pg-pool/index.js | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/packages/pg-pool/index.js b/packages/pg-pool/index.js
index 94004e031..17c7fbbd1 100644
--- a/packages/pg-pool/index.js
+++ b/packages/pg-pool/index.js
@@ -156,7 +156,7 @@ class Pool extends EventEmitter {
     throw new Error('unexpected condition')
   }
 
-  _remove(client) {
+  _remove(client, callback) {
     const removed = removeWhere(this._idle, (item) => item.client === client)
 
     if (removed !== undefined) {
@@ -164,8 +164,13 @@ class Pool extends EventEmitter {
     }
 
     this._clients = this._clients.filter((c) => c !== client)
-    client.end()
-    this.emit('remove', client)
+    client.end(() => {
+      this.emit('remove', client)
+
+      if (typeof callback === "function") {
+        callback()
+      }
+    }) 
   }
 
   connect(cb) {
@@ -342,17 +347,15 @@ class Pool extends EventEmitter {
       if (client._poolUseCount >= this.options.maxUses) {
         this.log('remove expended client')
       }
-      this._remove(client)
-      this._pulseQueue()
-      return
+
+      return  this._remove(client, this._pulseQueue.bind(this))
     }
 
     const isExpired = this._expired.has(client)
     if (isExpired) {
       this.log('remove expired client')
       this._expired.delete(client)
-      this._remove(client)
-      this._pulseQueue()
+      this._remove(client, this._pulseQueue.bind(this))
       return
     }
 
@@ -361,7 +364,7 @@ class Pool extends EventEmitter {
     if (this.options.idleTimeoutMillis) {
       tid = setTimeout(() => {
         this.log('remove idle client')
-        this._remove(client)
+        this._remove(client, this._pulseQueue.bind(this))
       }, this.options.idleTimeoutMillis)
 
       if (this.options.allowExitOnIdle) {

From 009acb90ec8b1ef380e2c72b903cdcb059e7fedc Mon Sep 17 00:00:00 2001
From: Asadbek Raimov <asadbekraimov642@gmail.com>
Date: Wed, 12 Jun 2024 02:10:22 +0500
Subject: [PATCH 2/6] Add test for pool.end method

---
 packages/pg-pool/index.js       |  6 +++---
 packages/pg-pool/test/ending.js | 10 ++++++++++
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/packages/pg-pool/index.js b/packages/pg-pool/index.js
index 17c7fbbd1..72e9d6400 100644
--- a/packages/pg-pool/index.js
+++ b/packages/pg-pool/index.js
@@ -167,10 +167,10 @@ class Pool extends EventEmitter {
     client.end(() => {
       this.emit('remove', client)
 
-      if (typeof callback === "function") {
+      if (typeof callback === 'function') {
         callback()
       }
-    }) 
+    })
   }
 
   connect(cb) {
@@ -348,7 +348,7 @@ class Pool extends EventEmitter {
         this.log('remove expended client')
       }
 
-      return  this._remove(client, this._pulseQueue.bind(this))
+      return this._remove(client, this._pulseQueue.bind(this))
     }
 
     const isExpired = this._expired.has(client)
diff --git a/packages/pg-pool/test/ending.js b/packages/pg-pool/test/ending.js
index e1839b46c..d3aa81f05 100644
--- a/packages/pg-pool/test/ending.js
+++ b/packages/pg-pool/test/ending.js
@@ -37,4 +37,14 @@ describe('pool ending', () => {
       expect(res.rows[0].name).to.equal('brianc')
     })
   )
+
+  it('pool.end() - finish pending queries', async () => {
+    const pool = new Pool({ max: 20 })
+    let completed = 0
+    for (let x = 1; x <= 20; x++) {
+      pool.query('SELECT $1::text as name', ['brianc']).then(() => completed++)
+    }
+    await pool.end()
+    expect(completed).to.equal(20)
+  })
 })

From b90605119c5cc5b4c56778db0b418710172a1146 Mon Sep 17 00:00:00 2001
From: Asadbek Raimov <asadbekraimov642@gmail.com>
Date: Wed, 12 Jun 2024 12:12:17 +0500
Subject: [PATCH 3/6] fix: remove excessive _pulseQueue call

---
 packages/pg-pool/index.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/pg-pool/index.js b/packages/pg-pool/index.js
index 72e9d6400..861cce507 100644
--- a/packages/pg-pool/index.js
+++ b/packages/pg-pool/index.js
@@ -364,7 +364,7 @@ class Pool extends EventEmitter {
     if (this.options.idleTimeoutMillis) {
       tid = setTimeout(() => {
         this.log('remove idle client')
-        this._remove(client, this._pulseQueue.bind(this))
+        this._remove(client)
       }, this.options.idleTimeoutMillis)
 
       if (this.options.allowExitOnIdle) {

From 293cfa85bc03e42de4a55957b517253e3b330587 Mon Sep 17 00:00:00 2001
From: Asadbek Raimov <asadbekraimov642@gmail.com>
Date: Fri, 14 Jun 2024 20:56:21 +0500
Subject: [PATCH 4/6] fix: context problem

---
 packages/pg-pool/index.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/packages/pg-pool/index.js b/packages/pg-pool/index.js
index 861cce507..ad48a80be 100644
--- a/packages/pg-pool/index.js
+++ b/packages/pg-pool/index.js
@@ -164,8 +164,9 @@ class Pool extends EventEmitter {
     }
 
     this._clients = this._clients.filter((c) => c !== client)
+    const context = this
     client.end(() => {
-      this.emit('remove', client)
+      context.emit('remove', client)
 
       if (typeof callback === 'function') {
         callback()

From e81fc3d81148d108b8abc92ed116c002987707cb Mon Sep 17 00:00:00 2001
From: Asadbek Raimov <asadbekraimov642@gmail.com>
Date: Tue, 18 Jun 2024 00:41:48 +0500
Subject: [PATCH 5/6] fix: test resolve should be called when the last client
 is removed

---
 packages/pg-pool/test/idle-timeout.js | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/packages/pg-pool/test/idle-timeout.js b/packages/pg-pool/test/idle-timeout.js
index 0bb097565..13514bdb6 100644
--- a/packages/pg-pool/test/idle-timeout.js
+++ b/packages/pg-pool/test/idle-timeout.js
@@ -25,6 +25,7 @@ describe('idle timeout', () => {
   it(
     'times out and removes clients when others are also removed',
     co.wrap(function* () {
+      let currentClient = 1
       const pool = new Pool({ idleTimeoutMillis: 10 })
       const clientA = yield pool.connect()
       const clientB = yield pool.connect()
@@ -35,7 +36,12 @@ describe('idle timeout', () => {
         pool.on('remove', () => {
           expect(pool.idleCount).to.equal(0)
           expect(pool.totalCount).to.equal(0)
-          resolve()
+
+          if (currentClient >= 2) {
+            resolve()
+          } else {
+            currentClient++
+          }
         })
       })
 

From 5e91617294e12b1acf2dc43082cb1982a91fc25b Mon Sep 17 00:00:00 2001
From: Asadbek Raimov <asadbekraimov642@gmail.com>
Date: Tue, 18 Jun 2024 18:26:57 +0500
Subject: [PATCH 6/6] fix: wait for pool.end()

Because when you don't pass a callback to .end() it always returns a promise
---
 packages/pg-pool/index.js             | 5 ++---
 packages/pg-pool/test/idle-timeout.js | 2 +-
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/packages/pg-pool/index.js b/packages/pg-pool/index.js
index ad48a80be..c4e9b36aa 100644
--- a/packages/pg-pool/index.js
+++ b/packages/pg-pool/index.js
@@ -356,8 +356,7 @@ class Pool extends EventEmitter {
     if (isExpired) {
       this.log('remove expired client')
       this._expired.delete(client)
-      this._remove(client, this._pulseQueue.bind(this))
-      return
+      return this._remove(client, this._pulseQueue.bind(this))
     }
 
     // idle timeout
@@ -365,7 +364,7 @@ class Pool extends EventEmitter {
     if (this.options.idleTimeoutMillis) {
       tid = setTimeout(() => {
         this.log('remove idle client')
-        this._remove(client)
+        this._remove(client, this._pulseQueue.bind(this))
       }, this.options.idleTimeoutMillis)
 
       if (this.options.allowExitOnIdle) {
diff --git a/packages/pg-pool/test/idle-timeout.js b/packages/pg-pool/test/idle-timeout.js
index 13514bdb6..588cf9bd4 100644
--- a/packages/pg-pool/test/idle-timeout.js
+++ b/packages/pg-pool/test/idle-timeout.js
@@ -50,7 +50,7 @@ describe('idle timeout', () => {
       try {
         yield Promise.race([removal, timeout])
       } finally {
-        pool.end()
+        yield pool.end()
       }
     })
   )