diff --git a/lib/pg/connection.rb b/lib/pg/connection.rb index 1b64410b..572a2bf5 100644 --- a/lib/pg/connection.rb +++ b/lib/pg/connection.rb @@ -680,7 +680,7 @@ module Pollable host_count = conninfo_hash[:host].to_s.count(",") + 1 stop_time = timeo * host_count + Process.clock_gettime(Process::CLOCK_MONOTONIC) end - connection_attempts = 1 + connection_errors = [] poll_status = PG::PGRES_POLLING_WRITING until poll_status == PG::PGRES_POLLING_OK || @@ -721,12 +721,12 @@ module Pollable else connhost = "at \"#{host}\", port #{port}" end - if connection_attempts < host_count.to_i - connection_attempts += 1 + connection_errors << "connection to server #{connhost} failed: timeout expired" + if connection_errors.count < host_count.to_i new_conninfo_hash = rotate_hosts(conninfo_hash.compact) send(:reset_start2, self.class.send(:parse_connect_args, new_conninfo_hash)) else - raise PG::ConnectionBad.new("connection to server #{connhost} failed: timeout expired", connection: self) + raise PG::ConnectionBad.new(connection_errors.join("\n"), connection: self) end end diff --git a/spec/pg/connection_spec.rb b/spec/pg/connection_spec.rb index e031d83c..15588fd3 100644 --- a/spec/pg/connection_spec.rb +++ b/spec/pg/connection_spec.rb @@ -369,25 +369,25 @@ end end - it "times out after connect_timeout seconds" do + it "times out after 2 * connect_timeout seconds on two connections" do TCPServer.open( 'localhost', 54320 ) do |serv| start_time = Time.now expect { described_class.connect( - host: 'localhost', + host: 'localhost,localhost', port: 54320, connect_timeout: 1, dbname: "test") }.to raise_error do |error| expect( error ).to be_an( PG::ConnectionBad ) - expect( error.message ).to match( /timeout expired/ ) + expect( error.message ).to match( /timeout expired.*timeout expired/m ) if PG.library_version >= 120000 - expect( error.message ).to match( /\"localhost\"/ ) + expect( error.message ).to match( /\"localhost\".*\"localhost\"/m ) expect( error.message ).to match( /port 54320/ ) end end - expect( Time.now - start_time ).to be_between(0.9, 10).inclusive + expect( Time.now - start_time ).to be_between(1.9, 10).inclusive end end