aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/libpq/fe-connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/libpq/fe-connect.c')
-rw-r--r--src/interfaces/libpq/fe-connect.c35
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;
}
/*