mirror of
https://github.com/postgres/postgres.git
synced 2025-07-07 00:36:50 +03:00
Add support TCP user timeout in libpq and the backend server
Similarly to the set of parameters for keepalive, a connection parameter for libpq is added as well as a backend GUC, called tcp_user_timeout. Increasing the TCP user timeout is useful to allow a connection to survive extended periods without end-to-end connection, and decreasing it allows application to fail faster. By default, the parameter is 0, which makes the connection use the system default, and follows a logic close to the keepalive parameters in its handling. When connecting through a Unix-socket domain, the parameters have no effect. Author: Ryohei Nagaura Reviewed-by: Fabien Coelho, Robert Haas, Kyotaro Horiguchi, Kirk Jamison, Mikalai Keida, Takayuki Tsunakawa, Andrei Yahorau Discussion: https://postgr.es/m/EDA4195584F5064680D8130B1CA91C45367328@G01JPEXMBYT04
This commit is contained in:
@ -270,6 +270,10 @@ static const internalPQconninfoOption PQconninfoOptions[] = {
|
||||
"TCP-Keepalives-Count", "", 10, /* strlen(INT32_MAX) == 10 */
|
||||
offsetof(struct pg_conn, keepalives_count)},
|
||||
|
||||
{"tcp_user_timeout", NULL, NULL, NULL,
|
||||
"TCP-User-Timeout", "", 10, /* strlen(INT32_MAX) == 10 */
|
||||
offsetof(struct pg_conn, pgtcp_user_timeout)},
|
||||
|
||||
/*
|
||||
* ssl options are allowed even without client SSL support because the
|
||||
* client can still handle SSL modes "disable" and "allow". Other
|
||||
@ -1833,6 +1837,41 @@ setKeepalivesWin32(PGconn *conn)
|
||||
#endif /* SIO_KEEPALIVE_VALS */
|
||||
#endif /* WIN32 */
|
||||
|
||||
/*
|
||||
* Set the TCP user timeout.
|
||||
*/
|
||||
static int
|
||||
setTCPUserTimeout(PGconn *conn)
|
||||
{
|
||||
int timeout;
|
||||
|
||||
if (conn->pgtcp_user_timeout == NULL)
|
||||
return 1;
|
||||
|
||||
if (!parse_int_param(conn->pgtcp_user_timeout, &timeout, conn,
|
||||
"tcp_user_timeout"))
|
||||
return 0;
|
||||
|
||||
if (timeout < 0)
|
||||
timeout = 0;
|
||||
|
||||
#ifdef TCP_USER_TIMEOUT
|
||||
if (setsockopt(conn->sock, IPPROTO_TCP, TCP_USER_TIMEOUT,
|
||||
(char *) &timeout, sizeof(timeout)) < 0)
|
||||
{
|
||||
char sebuf[256];
|
||||
|
||||
appendPQExpBuffer(&conn->errorMessage,
|
||||
libpq_gettext("setsockopt(%s) failed: %s\n"),
|
||||
"TCP_USER_TIMEOUT",
|
||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ----------
|
||||
* connectDBStart -
|
||||
* Begin the process of making a connection to the backend.
|
||||
@ -2480,6 +2519,8 @@ keep_going: /* We will come back to here until there is
|
||||
err = 1;
|
||||
#endif /* SIO_KEEPALIVE_VALS */
|
||||
#endif /* WIN32 */
|
||||
else if (!setTCPUserTimeout(conn))
|
||||
err = 1;
|
||||
|
||||
if (err)
|
||||
{
|
||||
@ -3863,6 +3904,8 @@ freePGconn(PGconn *conn)
|
||||
free(conn->pgtty);
|
||||
if (conn->connect_timeout)
|
||||
free(conn->connect_timeout);
|
||||
if (conn->pgtcp_user_timeout)
|
||||
free(conn->pgtcp_user_timeout);
|
||||
if (conn->pgoptions)
|
||||
free(conn->pgoptions);
|
||||
if (conn->appname)
|
||||
|
@ -336,6 +336,7 @@ struct pg_conn
|
||||
char *pgtty; /* tty on which the backend messages is
|
||||
* displayed (OBSOLETE, NOT USED) */
|
||||
char *connect_timeout; /* connection timeout (numeric string) */
|
||||
char *pgtcp_user_timeout; /* tcp user timeout (numeric string) */
|
||||
char *client_encoding_initial; /* encoding to use */
|
||||
char *pgoptions; /* options to start the backend with */
|
||||
char *appname; /* application name */
|
||||
|
Reference in New Issue
Block a user