class PG::Connection
def connect_to_hosts(*args)
def connect_to_hosts(*args) string = parse_connect_args(*args) PG::Connection.conninfo_parse(option_string).each_with_object({}){|h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] } PG::Connection.conndefaults.each_with_object({}){|h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] }.merge(iopts) s[:hostaddr] addr is provided -> no need to resolve hostnames opts[:host] && !iopts[:host].empty? && PG.library_version >= 100000 lve DNS in Ruby to avoid blocking state while connecting. iple comma-separated values are generated, if the hostname resolves to both IPv4 and IPv6 addresses. requires PostgreSQL-10+, so no DNS resolving is done on earlier versions. = iopts[:host].split(",", -1) = iopts[:port].split(",", -1) = [nil] if iports.size == 0 = iports * ihosts.size if iports.size == 1 PG::ConnectionBad, "could not match #{iports.size} port numbers to #{ihosts.size} hosts" if iports.size != ihosts.size = ihosts.each_with_index.flat_map do |mhost, idx| s host_is_named_pipe?(mhost) iber.respond_to?(:scheduler) && iber.scheduler && UBY_VERSION < '3.1.' se a second thread to avoid blocking of the scheduler. TCPSocket.gethostbyname` isn't fiber aware before ruby-3.1. taddrs = Thread.new{ Addrinfo.getaddrinfo(mhost, nil, nil, :STREAM).map(&:ip_address) rescue [''] }.value taddrs = Addrinfo.getaddrinfo(mhost, nil, nil, :STREAM).map(&:ip_address) rescue [''] hostname to resolve (UnixSocket) addrs = [nil] ddrs.map { |hostaddr| [hostaddr, mhost, iports[idx]] } merge!( ddr: dests.map{|d| d[0] }.join(","), dests.map{|d| d[1] }.join(","), dests.map{|d| d[2] }.join(",")) ost given self.connect_start(iopts) or raise(PG::Error, "Unable to create a new connection") G::ConnectionBad, conn.error_message if conn.status == PG::CONNECTION_BAD nd(:async_connect_or_reset, :connect_poll)