<term><literal>connect_timeout</literal></term>
<listitem>
<para>
- Maximum wait for connection, in seconds (write as a decimal integer
- string). Zero or not specified means wait indefinitely. It is not
- recommended to use a timeout of less than 2 seconds.
- This timeout applies separately to each connection attempt.
+ Maximum wait for connection, in seconds (write as a decimal integer,
+ e.g. <literal>10</literal>). Zero, negative, or not specified means
+ wait indefinitely. The minimum allowed timeout is 2 seconds, therefore
+ a value of <literal>1</literal> is interpreted as <literal>2</literal>.
+ This timeout applies separately to each host name or IP address.
For example, if you specify two hosts and <literal>connect_timeout</literal>
is 5, each host will time out if no connection is made within 5
seconds, so the total time spent waiting for a connection might be
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;
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;
}
}
{
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.
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;
}
/*