From c10553bf46b3a8503e673bb01476e8575aef2b9a Mon Sep 17 00:00:00 2001
From: Garet Halliday <me@garet.holiday>
Date: Fri, 8 Sep 2023 14:28:35 -0500
Subject: [PATCH] remove and close old pools

---
 .../zalando_operator_discovery/server.go      |  8 +++++
 lib/gat/pool/pool.go                          | 31 +++++++++++++++++++
 lib/gat/pools.go                              |  5 +--
 3 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/lib/gat/modes/zalando_operator_discovery/server.go b/lib/gat/modes/zalando_operator_discovery/server.go
index d3e45940..ad5fb595 100644
--- a/lib/gat/modes/zalando_operator_discovery/server.go
+++ b/lib/gat/modes/zalando_operator_discovery/server.go
@@ -106,6 +106,14 @@ func (T *Server) updatePostgresql(oldPsql *v1acid.Postgresql, newPsql *v1acid.Po
 	if oldPsql != nil {
 		log.Print("removed databases: ", oldPsql.Spec.Databases)
 		log.Print("removed users: ", oldPsql.Spec.Users)
+		for user := range oldPsql.Spec.Users {
+			for database := range oldPsql.Spec.Databases {
+				p := T.pools.Remove(user, database)
+				if p != nil {
+					p.Close()
+				}
+			}
+		}
 	}
 	if newPsql != nil {
 		log.Print("added databases: ", newPsql.Spec.Databases)
diff --git a/lib/gat/pool/pool.go b/lib/gat/pool/pool.go
index f1d435d1..6ebc5f99 100644
--- a/lib/gat/pool/pool.go
+++ b/lib/gat/pool/pool.go
@@ -19,6 +19,8 @@ import (
 type Pool struct {
 	options Options
 
+	closed chan struct{}
+
 	recipes         map[string]*recipe.Recipe
 	clients         map[uuid.UUID]*Client
 	clientsByKey    map[[8]byte]*Client
@@ -29,6 +31,7 @@ type Pool struct {
 
 func NewPool(options Options) *Pool {
 	p := &Pool{
+		closed:  make(chan struct{}),
 		options: options,
 	}
 
@@ -60,6 +63,12 @@ func (T *Pool) idlest() (server *Server, at time.Time) {
 
 func (T *Pool) idleLoop() {
 	for {
+		select {
+		case <-T.closed:
+			return
+		default:
+		}
+
 		var wait time.Duration
 
 		now := time.Now()
@@ -311,6 +320,11 @@ func (T *Pool) removeClient(client *Client) {
 	T.mu.Lock()
 	defer T.mu.Unlock()
 
+	T.removeClientL1(client)
+}
+
+func (T *Pool) removeClientL1(client *Client) {
+	_ = client.conn.Close()
 	delete(T.clients, client.GetID())
 	delete(T.clientsByKey, client.GetBackendKey())
 }
@@ -365,3 +379,20 @@ func (T *Pool) ReadMetrics(m *metrics.Pool) {
 		m.Servers[id] = mc
 	}
 }
+
+func (T *Pool) Close() {
+	close(T.closed)
+
+	T.mu.Lock()
+	defer T.mu.Unlock()
+
+	// remove clients
+	for _, client := range T.clients {
+		T.removeClient(client)
+	}
+
+	// remove recipes
+	for name := range T.recipes {
+		T.removeRecipe(name)
+	}
+}
diff --git a/lib/gat/pools.go b/lib/gat/pools.go
index f9331ec5..850cc4b4 100644
--- a/lib/gat/pools.go
+++ b/lib/gat/pools.go
@@ -36,11 +36,12 @@ func (T *PoolsMap) Add(user, database string, pool *pool.Pool) {
 	}, pool)
 }
 
-func (T *PoolsMap) Remove(user, database string) {
-	T.pools.Delete(mapKey{
+func (T *PoolsMap) Remove(user, database string) *pool.Pool {
+	p, _ := T.pools.LoadAndDelete(mapKey{
 		User:     user,
 		Database: database,
 	})
+	return p
 }
 
 func (T *PoolsMap) Lookup(user, database string) *pool.Pool {
-- 
GitLab