diff --git a/src/stats.rs b/src/stats.rs index 90b55ddd..e37c88c7 100644 --- a/src/stats.rs +++ b/src/stats.rs @@ -740,7 +740,10 @@ impl Collector { address_id, } => { match client_states.get_mut(&client_id) { - Some(client_info) => client_info.error_count += stat.value as u64, + Some(client_info) => { + client_info.state = ClientState::Idle; + client_info.error_count += stat.value as u64; + } None => warn!("Got event {:?} for unregistered client", stat.name), } @@ -757,7 +760,10 @@ impl Collector { address_id, } => { match client_states.get_mut(&client_id) { - Some(client_info) => client_info.error_count += stat.value as u64, + Some(client_info) => { + client_info.state = ClientState::Idle; + client_info.error_count += stat.value as u64; + } None => warn!("Got event {:?} for unregistered client", stat.name), } diff --git a/tests/ruby/admin_spec.rb b/tests/ruby/admin_spec.rb index a348146e..3bc12641 100644 --- a/tests/ruby/admin_spec.rb +++ b/tests/ruby/admin_spec.rb @@ -146,6 +146,36 @@ end end + context "client fail to checkout connection from the pool" do + it "counts clients as idle" do + new_configs = processes.pgcat.current_config + new_configs["general"]["connect_timeout"] = 500 + new_configs["general"]["ban_time"] = 1 + new_configs["general"]["shutdown_timeout"] = 1 + new_configs["pools"]["sharded_db"]["users"]["0"]["pool_size"] = 1 + processes.pgcat.update_config(new_configs) + processes.pgcat.reload_config + + threads = [] + connections = Array.new(5) { PG::connect("#{pgcat_conn_str}?application_name=one_query") } + connections.each do |c| + threads << Thread.new { c.async_exec("SELECT pg_sleep(1)") rescue PG::SystemError } + end + + sleep(2) + admin_conn = PG::connect(processes.pgcat.admin_connection_string) + results = admin_conn.async_exec("SHOW POOLS")[0] + %w[cl_active cl_waiting cl_cancel_req sv_active sv_used sv_tested sv_login maxwait].each do |s| + raise StandardError, "Field #{s} was expected to be 0 but found to be #{results[s]}" if results[s] != "0" + end + expect(results["cl_idle"]).to eq("5") + expect(results["sv_idle"]).to eq("1") + + threads.map(&:join) + connections.map(&:close) + end + end + context "clients overwhelm server pools" do let(:processes) { Helpers::Pgcat.single_instance_setup("sharded_db", 2) }