aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/libpq/fe-connect.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2017-05-19 16:19:51 -0400
committerRobert Haas <rhaas@postgresql.org>2017-05-19 16:19:51 -0400
commit5f374fe7a83304fd339789da22599bd102dac9e5 (patch)
tree42bbf462f55a505452e107074fe06ecfe925348e /src/interfaces/libpq/fe-connect.c
parentaa41bc794c51a4d5c364cca014c199b1a00d26aa (diff)
downloadpostgresql-5f374fe7a83304fd339789da22599bd102dac9e5.tar.gz
postgresql-5f374fe7a83304fd339789da22599bd102dac9e5.zip
libpq: Try next host if one of them times out.
If one host in a multi-host connection string times out, move on to the next specified host instead of giving up entirely. Takayuki Tsunakawa, reviewed by Michael Paquier. I added a minor adjustment to the documentation. Discussion: http://postgr.es/m/0A3221C70F24FB45833433255569204D1F6F42F5@G01JPEXMBYT05
Diffstat (limited to 'src/interfaces/libpq/fe-connect.c')
-rw-r--r--src/interfaces/libpq/fe-connect.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 8e3ef4b9f75..f2c9bf7a883 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -1720,6 +1720,7 @@ connectDBComplete(PGconn *conn)
{
PostgresPollingStatusType flag = PGRES_POLLING_WRITING;
time_t finish_time = ((time_t) -1);
+ int timeout = 0;
if (conn == NULL || conn->status == CONNECTION_BAD)
return 0;
@@ -1729,8 +1730,7 @@ connectDBComplete(PGconn *conn)
*/
if (conn->connect_timeout != NULL)
{
- int timeout = atoi(conn->connect_timeout);
-
+ timeout = atoi(conn->connect_timeout);
if (timeout > 0)
{
/*
@@ -1745,6 +1745,8 @@ connectDBComplete(PGconn *conn)
for (;;)
{
+ int ret = 0;
+
/*
* Wait, if necessary. Note that the initial state (just after
* PQconnectStart) is to wait for the socket to select for writing.
@@ -1761,7 +1763,8 @@ connectDBComplete(PGconn *conn)
return 1; /* success! */
case PGRES_POLLING_READING:
- if (pqWaitTimed(1, 0, conn, finish_time))
+ ret = pqWaitTimed(1, 0, conn, finish_time);
+ if (ret == -1)
{
conn->status = CONNECTION_BAD;
return 0;
@@ -1769,7 +1772,8 @@ connectDBComplete(PGconn *conn)
break;
case PGRES_POLLING_WRITING:
- if (pqWaitTimed(0, 1, conn, finish_time))
+ ret = pqWaitTimed(0, 1, conn, finish_time);
+ if (ret == -1)
{
conn->status = CONNECTION_BAD;
return 0;
@@ -1782,6 +1786,23 @@ connectDBComplete(PGconn *conn)
return 0;
}
+ if (ret == 1) /* connect_timeout elapsed */
+ {
+ /* If there are no more hosts, return (the error message is already set) */
+ if (++conn->whichhost >= conn->nconnhost)
+ {
+ conn->whichhost = 0;
+ conn->status = CONNECTION_BAD;
+ return 0;
+ }
+ /* Attempt connection to the next host, starting the connect_timeout timer */
+ pqDropConnection(conn, true);
+ conn->addr_cur = conn->connhost[conn->whichhost].addrlist;
+ conn->status = CONNECTION_NEEDED;
+ if (conn->connect_timeout != NULL)
+ finish_time = time(NULL) + timeout;
+ }
+
/*
* Now try to advance the state machine.
*/