From c9544bdff29600cf23acdac385575c0e3946a80f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Fern=C3=A1ndez?= Date: Thu, 7 Nov 2024 18:11:49 +0100 Subject: [PATCH] Fix `default_role` being ignored when `query_parser_enabled` was false (#847) Fix default_role being ignored when query_parser_enabled was false --- src/client.rs | 1 + src/query_router.rs | 5 +++++ tests/ruby/load_balancing_spec.rb | 36 ++++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/client.rs b/src/client.rs index 405d72be..c226436e 100644 --- a/src/client.rs +++ b/src/client.rs @@ -881,6 +881,7 @@ where }; query_router.update_pool_settings(&pool.settings); + query_router.set_default_role(); // Our custom protocol loop. // We expect the client to either start a transaction with regular queries diff --git a/src/query_router.rs b/src/query_router.rs index cc502a0d..59cca232 100644 --- a/src/query_router.rs +++ b/src/query_router.rs @@ -1061,6 +1061,11 @@ impl QueryRouter { self.active_shard } + /// Set active_role as the default_role specified in the pool. + pub fn set_default_role(&mut self) { + self.active_role = self.pool_settings.default_role; + } + /// Get the current desired server role we should be talking to. pub fn role(&self) -> Option { self.active_role diff --git a/tests/ruby/load_balancing_spec.rb b/tests/ruby/load_balancing_spec.rb index 172e6069..f00f8db1 100644 --- a/tests/ruby/load_balancing_spec.rb +++ b/tests/ruby/load_balancing_spec.rb @@ -56,6 +56,41 @@ end end end + + context "when all replicas are down " do + let(:processes) { Helpers::Pgcat.single_shard_setup("sharded_db", 5, "transaction", "random", "debug", {"default_role" => "replica"}) } + + it "unbans them automatically to prevent false positives in health checks that could make all replicas unavailable" do + conn = PG.connect(processes.pgcat.connection_string("sharded_db", "sharding_user")) + failed_count = 0 + number_of_replicas = processes[:replicas].length + + # Take down all replicas + processes[:replicas].each(&:take_down) + + (number_of_replicas + 1).times do |n| + conn.async_exec("SELECT 1 + 2") + rescue + conn = PG.connect(processes.pgcat.connection_string("sharded_db", "sharding_user")) + failed_count += 1 + end + + expect(failed_count).to eq(number_of_replicas + 1) + failed_count = 0 + + # Ban_time is configured to 60 so this reset will only work + # if the replicas are unbanned automatically + processes[:replicas].each(&:reset) + + number_of_replicas.times do + conn.async_exec("SELECT 1 + 2") + rescue + conn = PG.connect(processes.pgcat.connection_string("sharded_db", "sharding_user")) + failed_count += 1 + end + expect(failed_count).to eq(0) + end + end end describe "Least Outstanding Queries Load Balancing" do @@ -161,4 +196,3 @@ end end end -