From f76e77341b5f8e98fc93726173a328eccd50c189 Mon Sep 17 00:00:00 2001
From: Garet Halliday <ghalliday@gfxlabs.io>
Date: Mon, 12 Sep 2022 18:14:39 -0500
Subject: [PATCH] allow multiple replicas

---
 README.md                              |  4 ++--
 lib/gat/gatling/conn_pool/conn_pool.go | 10 +++++-----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/README.md b/README.md
index 11605e13..4bd71f57 100644
--- a/README.md
+++ b/README.md
@@ -21,8 +21,8 @@ PostgreSQL pooler (like PgBouncer) with sharding, load balancing and failover su
 | Transaction pooling            | :white_check_mark:          | :white_check_mark: | Identical to PgBouncer.                                                                                                                               |
 | Session pooling                | :white_check_mark:          | :white_check_mark: | Identical to PgBouncer.                                                                                                                               |
 | `COPY` support                 | :white_check_mark:          | :white_check_mark: | Both `COPY TO` and `COPY FROM` are supported.                                                                                                         |
-| Query cancellation             | :white_check_mark:          | no                 | Supported both in transaction and session pooling modes.                                                                                              |
-| Load balancing of read queries | :white_check_mark:          | no                 | Using random between replicas. Primary is included when `primary_reads_enabled` is enabled (default).                                            |
+| Query cancellation             | :white_check_mark:          | :white_check_mark: | Supported both in transaction and session pooling modes.                                                                                              |
+| Load balancing of read queries | :white_check_mark:          | :white_check_mark: | Using random between replicas. Primary is included when `primary_reads_enabled` is enabled (default).                                            |
 | Sharding                       | :white_check_mark:          | no                 | Transactions are sharded using `SET SHARD TO` and `SET SHARDING KEY TO` syntax extensions; see examples below.                                        |
 | Failover                       | :white_check_mark:          | no                 | Replicas are tested with a health check. If a health check fails, remaining replicas are attempted; see below for algorithm description and examples. |
 | Statistics                     | :white_check_mark:          | no                 | Statistics available in the admin database (`pgcat` and `pgbouncer`) with `SHOW STATS`, `SHOW POOLS` and others.                                      |
diff --git a/lib/gat/gatling/conn_pool/conn_pool.go b/lib/gat/gatling/conn_pool/conn_pool.go
index 6f8fe055..74347af6 100644
--- a/lib/gat/gatling/conn_pool/conn_pool.go
+++ b/lib/gat/gatling/conn_pool/conn_pool.go
@@ -16,8 +16,8 @@ import (
 )
 
 type connections struct {
-	primary *server.Server
-	replica *server.Server
+	primary  *server.Server
+	replicas []*server.Server
 
 	mu sync.Mutex
 }
@@ -27,11 +27,11 @@ func (s *connections) choose(role config.ServerRole) *server.Server {
 	case config.SERVERROLE_PRIMARY:
 		return s.primary
 	case config.SERVERROLE_REPLICA:
-		if s.replica == nil {
+		if len(s.replicas) == 0 {
 			// fallback to primary
 			return s.primary
 		}
-		return s.replica
+		return s.replicas[rand.Intn(len(s.replicas))]
 	default:
 		return nil
 	}
@@ -141,7 +141,7 @@ func (c *ConnectionPool) chooseConnections() *connections {
 		case config.SERVERROLE_PRIMARY:
 			srvs.primary = srv
 		case config.SERVERROLE_REPLICA:
-			srvs.replica = srv
+			srvs.replicas = append(srvs.replicas, srv)
 		}
 	}
 	if srvs.primary == nil {
-- 
GitLab