Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5f374fe

Browse files
committed
libpq: Try next host if one of them times out.
If one host in a multi-host connection string times out, move on tothe next specified host instead of giving up entirely.Takayuki Tsunakawa, reviewed by Michael Paquier. I addeda minor adjustment to the documentation.Discussion:http://postgr.es/m/0A3221C70F24FB45833433255569204D1F6F42F5@G01JPEXMBYT05
1 parentaa41bc7 commit5f374fe

File tree

3 files changed

+33
-13
lines changed

3 files changed

+33
-13
lines changed

‎doc/src/sgml/libpq.sgml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,9 +1041,10 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
10411041
string). Zero or not specified means wait indefinitely. It is not
10421042
recommended to use a timeout of less than 2 seconds.
10431043
This timeout applies separately to each connection attempt.
1044-
For example, if you specify two hosts and both of them are unreachable,
1045-
and <literal>connect_timeout</> is 5, the total time spent waiting for a
1046-
connection might be up to 10 seconds.
1044+
For example, if you specify two hosts and <literal>connect_timeout</>
1045+
is 5, each host will time out if no connection is made within 5
1046+
seconds, so the total time spent waiting for a connection might be
1047+
up to 10 seconds.
10471048
</para>
10481049
</listitem>
10491050
</varlistentry>

‎src/interfaces/libpq/fe-connect.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,6 +1720,7 @@ connectDBComplete(PGconn *conn)
17201720
{
17211721
PostgresPollingStatusTypeflag=PGRES_POLLING_WRITING;
17221722
time_tfinish_time= ((time_t)-1);
1723+
inttimeout=0;
17231724

17241725
if (conn==NULL||conn->status==CONNECTION_BAD)
17251726
return0;
@@ -1729,8 +1730,7 @@ connectDBComplete(PGconn *conn)
17291730
*/
17301731
if (conn->connect_timeout!=NULL)
17311732
{
1732-
inttimeout=atoi(conn->connect_timeout);
1733-
1733+
timeout=atoi(conn->connect_timeout);
17341734
if (timeout>0)
17351735
{
17361736
/*
@@ -1745,6 +1745,8 @@ connectDBComplete(PGconn *conn)
17451745

17461746
for (;;)
17471747
{
1748+
intret=0;
1749+
17481750
/*
17491751
* Wait, if necessary. Note that the initial state (just after
17501752
* PQconnectStart) is to wait for the socket to select for writing.
@@ -1761,15 +1763,17 @@ connectDBComplete(PGconn *conn)
17611763
return1;/* success! */
17621764

17631765
casePGRES_POLLING_READING:
1764-
if (pqWaitTimed(1,0,conn,finish_time))
1766+
ret=pqWaitTimed(1,0,conn,finish_time);
1767+
if (ret==-1)
17651768
{
17661769
conn->status=CONNECTION_BAD;
17671770
return0;
17681771
}
17691772
break;
17701773

17711774
casePGRES_POLLING_WRITING:
1772-
if (pqWaitTimed(0,1,conn,finish_time))
1775+
ret=pqWaitTimed(0,1,conn,finish_time);
1776+
if (ret==-1)
17731777
{
17741778
conn->status=CONNECTION_BAD;
17751779
return0;
@@ -1782,6 +1786,23 @@ connectDBComplete(PGconn *conn)
17821786
return0;
17831787
}
17841788

1789+
if (ret==1)/* connect_timeout elapsed */
1790+
{
1791+
/* If there are no more hosts, return (the error message is already set) */
1792+
if (++conn->whichhost >=conn->nconnhost)
1793+
{
1794+
conn->whichhost=0;
1795+
conn->status=CONNECTION_BAD;
1796+
return0;
1797+
}
1798+
/* Attempt connection to the next host, starting the connect_timeout timer */
1799+
pqDropConnection(conn, true);
1800+
conn->addr_cur=conn->connhost[conn->whichhost].addrlist;
1801+
conn->status=CONNECTION_NEEDED;
1802+
if (conn->connect_timeout!=NULL)
1803+
finish_time=time(NULL)+timeout;
1804+
}
1805+
17851806
/*
17861807
* Now try to advance the state machine.
17871808
*/

‎src/interfaces/libpq/fe-misc.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -991,11 +991,9 @@ pqWait(int forRead, int forWrite, PGconn *conn)
991991
/*
992992
* pqWaitTimed: wait, but not past finish_time.
993993
*
994-
* If finish_time is exceeded then we return failure (EOF). This is like
995-
* the response for a kernel exception because we don't want the caller
996-
* to try to read/write in that case.
997-
*
998994
* finish_time = ((time_t) -1) disables the wait limit.
995+
*
996+
* Returns -1 on failure, 0 if the socket is readable/writable, 1 if it timed out.
999997
*/
1000998
int
1001999
pqWaitTimed(intforRead,intforWrite,PGconn*conn,time_tfinish_time)
@@ -1005,13 +1003,13 @@ pqWaitTimed(int forRead, int forWrite, PGconn *conn, time_t finish_time)
10051003
result=pqSocketCheck(conn,forRead,forWrite,finish_time);
10061004

10071005
if (result<0)
1008-
returnEOF;/* errorMessage is already set */
1006+
return-1;/* errorMessage is already set */
10091007

10101008
if (result==0)
10111009
{
10121010
printfPQExpBuffer(&conn->errorMessage,
10131011
libpq_gettext("timeout expired\n"));
1014-
returnEOF;
1012+
return1;
10151013
}
10161014

10171015
return0;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp