diff options
Diffstat (limited to 'src/interfaces/libpq/fe-connect.c')
-rw-r--r-- | src/interfaces/libpq/fe-connect.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index f9a5db5611f..c59b5c7bf05 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -1904,6 +1904,8 @@ connectDBComplete(PGconn *conn) PostgresPollingStatusType flag = PGRES_POLLING_WRITING; time_t finish_time = ((time_t) -1); int timeout = 0; + int last_whichhost = -2; /* certainly different from whichhost */ + struct addrinfo *last_addr_cur = NULL; if (conn == NULL || conn->status == CONNECTION_BAD) return 0; @@ -1917,12 +1919,12 @@ connectDBComplete(PGconn *conn) if (timeout > 0) { /* - * Rounding could cause connection to fail; need at least 2 secs + * Rounding could cause connection to fail unexpectedly quickly; + * to prevent possibly waiting hardly-at-all, insist on at least + * two seconds. */ if (timeout < 2) timeout = 2; - /* calculate the finish time based on start + timeout */ - finish_time = time(NULL) + timeout; } } @@ -1931,6 +1933,21 @@ connectDBComplete(PGconn *conn) int ret = 0; /* + * (Re)start the connect_timeout timer if it's active and we are + * considering a different host than we were last time through. If + * we've already succeeded, though, needn't recalculate. + */ + if (flag != PGRES_POLLING_OK && + timeout > 0 && + (conn->whichhost != last_whichhost || + conn->addr_cur != last_addr_cur)) + { + finish_time = time(NULL) + timeout; + last_whichhost = conn->whichhost; + last_addr_cur = conn->addr_cur; + } + + /* * Wait, if necessary. Note that the initial state (just after * PQconnectStart) is to wait for the socket to select for writing. */ @@ -1974,18 +1991,10 @@ connectDBComplete(PGconn *conn) if (ret == 1) /* connect_timeout elapsed */ { /* - * Attempt connection to the next host, ignoring any remaining - * addresses for the current host. + * Give up on current server/address, try the next one. */ - conn->try_next_addr = false; - conn->try_next_host = true; + conn->try_next_addr = true; conn->status = CONNECTION_NEEDED; - - /* - * Restart the connect_timeout timer for the new host. - */ - if (timeout > 0) - finish_time = time(NULL) + timeout; } /* |