Skip to content

Commit 9056826

Browse files
authored
Client keep alive, enabled by default (#609)
1 parent b20293b commit 9056826

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

client/src/lib.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ pub struct ClientOptions {
122122
/// override.
123123
#[builder(default)]
124124
pub override_origin: Option<Uri>,
125+
126+
/// If set (which it is by default), HTTP2 gRPC keep alive will be enabled.
127+
#[builder(default = "Some(ClientKeepAliveConfig::default())")]
128+
pub keep_alive: Option<ClientKeepAliveConfig>,
125129
}
126130

127131
/// Configuration options for TLS
@@ -147,6 +151,24 @@ pub struct ClientTlsConfig {
147151
pub client_private_key: Vec<u8>,
148152
}
149153

154+
/// Client keep alive configuration.
155+
#[derive(Clone, Debug)]
156+
pub struct ClientKeepAliveConfig {
157+
/// Interval to send HTTP2 keep alive pings.
158+
pub interval: Duration,
159+
/// Timeout that the keep alive must be responded to within or the connection will be closed.
160+
pub timeout: Duration,
161+
}
162+
163+
impl Default for ClientKeepAliveConfig {
164+
fn default() -> Self {
165+
Self {
166+
interval: Duration::from_secs(30),
167+
timeout: Duration::from_secs(15),
168+
}
169+
}
170+
}
171+
150172
/// Configuration for retrying requests to the server
151173
#[derive(Clone, Debug)]
152174
pub struct RetryConfig {
@@ -318,6 +340,14 @@ impl ClientOptions {
318340
{
319341
let channel = Channel::from_shared(self.target_url.to_string())?;
320342
let channel = self.add_tls_to_channel(channel).await?;
343+
let channel = if let Some(keep_alive) = self.keep_alive.as_ref() {
344+
channel
345+
.keep_alive_while_idle(true)
346+
.http2_keep_alive_interval(keep_alive.interval)
347+
.keep_alive_timeout(keep_alive.timeout)
348+
} else {
349+
channel
350+
};
321351
let channel = if let Some(origin) = self.override_origin.clone() {
322352
channel.origin(origin)
323353
} else {
@@ -1441,4 +1471,27 @@ mod tests {
14411471
let next_req = iceptor.call(req).unwrap();
14421472
assert_eq!(next_req.metadata().get("enchi").unwrap(), "cat");
14431473
}
1474+
1475+
#[test]
1476+
fn keep_alive_defaults() {
1477+
let mut builder = ClientOptionsBuilder::default();
1478+
builder
1479+
.identity("enchicat".to_string())
1480+
.target_url(Url::parse("https://smolkitty").unwrap())
1481+
.client_name("cute-kitty".to_string())
1482+
.client_version("0.1.0".to_string());
1483+
// If unset, defaults to Some
1484+
let opts = builder.build().unwrap();
1485+
assert_eq!(
1486+
opts.keep_alive.clone().unwrap().interval,
1487+
ClientKeepAliveConfig::default().interval
1488+
);
1489+
assert_eq!(
1490+
opts.keep_alive.clone().unwrap().timeout,
1491+
ClientKeepAliveConfig::default().timeout
1492+
);
1493+
// But can be set to none
1494+
let opts = builder.keep_alive(None).build().unwrap();
1495+
assert!(opts.keep_alive.is_none());
1496+
}
14441497
}

0 commit comments

Comments
 (0)