jackc / pgconn

MIT License
182 stars 87 forks source link

Connection Timeout prevents other db nodes from being attempted #125

Closed McDeez closed 2 years ago

McDeez commented 2 years ago

if there are several DB hosts in the config, and a timeout is set, and one of the DB hosts is not responsive, the next failback DB hosts will not be attempted due to the context being dead already. Moving the ConnectTimeout to inside of the failbackConfig loop allows each DB host to timeout and then create a new context for each subsequent DB host. If needs be can divide the overall timeout by the number of DBs to allow for a "max connection timeout for this entire connection string".

Also, need to eventually fix the error messages on this as the error messages always show as if the last host was errored out on dial (which is incorrect, and is only the last error to occur because the dialer's context is already dead).

Original bug replication that this fixes:

  1. localhost has a postgres database running on 5432
  2. open a netcat listener on port 5555 nc -lk 5555
  3. set connection string to: postgres://dbuser@localhost:5555,localhost:5432/mydb?target_session_attrs=read-write&connect_timeout=5
  4. initialize the pgconn

In this case the connection to 5555 will timeout at 5 seconds, and localhost:5432 (valid connection) will fail with a dialer error because the context timed out. The error message will erroneously state that localhost:5432 had a connection timeout.

jackc commented 2 years ago

LGTM