Skip to content

Commit 54a3c5e

Browse files
committed
add tcp user timeout config
1 parent 9c90862 commit 54a3c5e

File tree

6 files changed

+45
-2
lines changed

6 files changed

+45
-2
lines changed

Diff for: tokio-postgres/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ phf = "0.11"
5656
postgres-protocol = { version = "0.6.4", path = "../postgres-protocol" }
5757
postgres-types = { version = "0.2.4", path = "../postgres-types" }
5858
serde = { version = "1.0", optional = true }
59-
socket2 = "0.4"
59+
socket2 = { version = "0.4", features = ["all"] }
6060
tokio = { version = "1.0", features = ["io-util"] }
6161
tokio-util = { version = "0.7", features = ["codec"] }
6262

Diff for: tokio-postgres/src/cancel_query.rs

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ where
3838
&config.host,
3939
config.port,
4040
config.connect_timeout,
41+
config.tcp_user_timeout,
4142
config.keepalive.as_ref(),
4243
)
4344
.await?;

Diff for: tokio-postgres/src/client.rs

+1
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ pub(crate) struct SocketConfig {
158158
pub host: Host,
159159
pub port: u16,
160160
pub connect_timeout: Option<Duration>,
161+
pub tcp_user_timeout: Option<Duration>,
161162
pub keepalive: Option<KeepaliveConfig>,
162163
}
163164

Diff for: tokio-postgres/src/config.rs

+29
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ pub enum Host {
116116
/// omitted or the empty string.
117117
/// * `connect_timeout` - The time limit in seconds applied to each socket-level connection attempt. Note that hostnames
118118
/// can resolve to multiple IP addresses, and this limit is applied to each address. Defaults to no timeout.
119+
/// * `tcp_user_timeout` - The time limit that transmitted data may remain unacknowledged before a connection is forcibly closed.
120+
/// This is ignored for Unix domain socket connections. It is only supported on systems where TCP_USER_TIMEOUT is available
121+
/// and will default to the system default if omitted or set to 0; on other systems, it has no effect.
119122
/// * `keepalives` - Controls the use of TCP keepalive. A value of 0 disables keepalive and nonzero integers enable it.
120123
/// This option is ignored when connecting with Unix sockets. Defaults to on.
121124
/// * `keepalives_idle` - The number of seconds of inactivity after which a keepalive message is sent to the server.
@@ -183,6 +186,7 @@ pub struct Config {
183186
pub(crate) host: Vec<Host>,
184187
pub(crate) port: Vec<u16>,
185188
pub(crate) connect_timeout: Option<Duration>,
189+
pub(crate) tcp_user_timeout: Option<Duration>,
186190
pub(crate) keepalives: bool,
187191
pub(crate) keepalive_config: KeepaliveConfig,
188192
pub(crate) target_session_attrs: TargetSessionAttrs,
@@ -217,6 +221,7 @@ impl Config {
217221
host: vec![],
218222
port: vec![],
219223
connect_timeout: None,
224+
tcp_user_timeout: None,
220225
keepalives: true,
221226
keepalive_config,
222227
target_session_attrs: TargetSessionAttrs::Any,
@@ -407,6 +412,21 @@ impl Config {
407412
self.connect_timeout.as_ref()
408413
}
409414

415+
/// Sets the TCP user timeout.
416+
///
417+
/// This is ignored for Unix domain socket connections. It is only supported on systems where
418+
/// TCP_USER_TIMEOUT is available and will default to the system default if omitted or set to 0;
419+
/// on other systems, it has no effect.
420+
pub fn tcp_user_timeout(&mut self, tcp_user_timeout: Duration) -> &mut Config {
421+
self.tcp_user_timeout = Some(tcp_user_timeout);
422+
self
423+
}
424+
425+
/// Gets the TCP user timeout, if one has been set with the
426+
/// `user_timeout` method.
427+
pub fn get_tcp_user_timeout(&self) -> Option<&Duration> {
428+
self.tcp_user_timeout.as_ref()
429+
}
410430
/// Controls the use of TCP keepalive.
411431
///
412432
/// This is ignored for Unix domain socket connections. Defaults to `true`.
@@ -578,6 +598,14 @@ impl Config {
578598
self.connect_timeout(Duration::from_secs(timeout as u64));
579599
}
580600
}
601+
"tcp_user_timeout" => {
602+
let timeout = value
603+
.parse::<i64>()
604+
.map_err(|_| Error::config_parse(Box::new(InvalidValue("tcp_user_timeout"))))?;
605+
if timeout > 0 {
606+
self.tcp_user_timeout(Duration::from_secs(timeout as u64));
607+
}
608+
}
581609
"keepalives" => {
582610
let keepalives = value
583611
.parse::<u64>()
@@ -713,6 +741,7 @@ impl fmt::Debug for Config {
713741
.field("host", &self.host)
714742
.field("port", &self.port)
715743
.field("connect_timeout", &self.connect_timeout)
744+
.field("tcp_user_timeout", &self.tcp_user_timeout)
716745
.field("keepalives", &self.keepalives)
717746
.field("keepalives_idle", &self.keepalive_config.idle)
718747
.field("keepalives_interval", &self.keepalive_config.interval)

Diff for: tokio-postgres/src/connect.rs

+2
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ where
6565
host,
6666
port,
6767
config.connect_timeout,
68+
config.tcp_user_timeout,
6869
if config.keepalives {
6970
Some(&config.keepalive_config)
7071
} else {
@@ -118,6 +119,7 @@ where
118119
host: host.clone(),
119120
port,
120121
connect_timeout: config.connect_timeout,
122+
tcp_user_timeout: config.tcp_user_timeout,
121123
keepalive: if config.keepalives {
122124
Some(config.keepalive_config.clone())
123125
} else {

Diff for: tokio-postgres/src/connect_socket.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub(crate) async fn connect_socket(
1414
host: &Host,
1515
port: u16,
1616
connect_timeout: Option<Duration>,
17+
tcp_user_timeout: Option<Duration>,
1718
keepalive_config: Option<&KeepaliveConfig>,
1819
) -> Result<Socket, Error> {
1920
match host {
@@ -35,8 +36,17 @@ pub(crate) async fn connect_socket(
3536
};
3637

3738
stream.set_nodelay(true).map_err(Error::connect)?;
39+
40+
let sock_ref = SockRef::from(&stream);
41+
#[cfg(target_os = "linux")]
42+
{
43+
sock_ref
44+
.set_tcp_user_timeout(tcp_user_timeout)
45+
.map_err(Error::connect)?;
46+
}
47+
3848
if let Some(keepalive_config) = keepalive_config {
39-
SockRef::from(&stream)
49+
sock_ref
4050
.set_tcp_keepalive(&TcpKeepalive::from(keepalive_config))
4151
.map_err(Error::connect)?;
4252
}

0 commit comments

Comments
 (0)