diff options
author | Robert Haas <rhaas@postgresql.org> | 2017-05-19 16:19:51 -0400 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2017-05-19 16:19:51 -0400 |
commit | 5f374fe7a83304fd339789da22599bd102dac9e5 (patch) | |
tree | 42bbf462f55a505452e107074fe06ecfe925348e /src/interfaces/libpq/fe-connect.c | |
parent | aa41bc794c51a4d5c364cca014c199b1a00d26aa (diff) | |
download | postgresql-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.c | 29 |
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. */ |