Skip to content

Commit 32218e1

Browse files
committed
tonic: Server::default(): Set TCP_NODELAY to true; improve docs
The documentation of the Server::tcp_nodelay function said "Enabled by default", but that was only true when using Server::builder(). The default() method set this to false. To fix this: * Change Server::default() to set tcp_nodelay: true. * Change Server::builder() to just call Server::default(). * Add a test to verify the settings for nodelay and keepalive. * Document the functions to note that the TCP settings are ignored when using serve_with_incoming. I recently ran into problems where we accidentally "lost" the tcp_nodelay=true setting, due to refactoring some code to make it easier to test. This caused mysterious 40 ms latency increases. I hope this makes it less likely for others to make this mistake.
1 parent 03894a2 commit 32218e1

File tree

1 file changed

+37
-7
lines changed
  • tonic/src/transport/server

1 file changed

+37
-7
lines changed

tonic/src/transport/server/mod.rs

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ impl Default for Server<Identity> {
123123
init_connection_window_size: None,
124124
max_concurrent_streams: None,
125125
tcp_keepalive: None,
126-
tcp_nodelay: false,
126+
tcp_nodelay: true,
127127
http2_keepalive_interval: None,
128128
http2_keepalive_timeout: DEFAULT_HTTP2_KEEPALIVE_TIMEOUT,
129129
http2_adaptive_window: None,
@@ -148,11 +148,7 @@ pub struct Router<L = Identity> {
148148
impl Server {
149149
/// Create a new server builder that can configure a [`Server`].
150150
pub fn builder() -> Self {
151-
Server {
152-
tcp_nodelay: true,
153-
accept_http1: false,
154-
..Default::default()
155-
}
151+
Self::default()
156152
}
157153
}
158154

@@ -346,7 +342,7 @@ impl<L> Server<L> {
346342
/// specified will be the time to remain idle before sending TCP keepalive
347343
/// probes.
348344
///
349-
/// Important: This setting is only respected when not using `serve_with_incoming`.
345+
/// Important: This setting is not respected when using `serve_with_incoming`.
350346
///
351347
/// Default is no keepalive (`None`)
352348
///
@@ -359,6 +355,8 @@ impl<L> Server<L> {
359355
}
360356

361357
/// Set the value of `TCP_NODELAY` option for accepted connections. Enabled by default.
358+
///
359+
/// Important: This setting is not respected when using `serve_with_incoming`.
362360
#[must_use]
363361
pub fn tcp_nodelay(self, enabled: bool) -> Self {
364362
Server {
@@ -607,6 +605,8 @@ impl<L> Server<L> {
607605
}
608606

609607
/// Serve the service on the provided incoming stream.
608+
///
609+
/// The `tcp_nodelay` and `tcp_keepalive` settings are not respected when using this method.
610610
pub async fn serve_with_incoming<S, I, IO, IE, ResBody>(
611611
self,
612612
svc: S,
@@ -1154,3 +1154,33 @@ where
11541154
}
11551155
}
11561156
}
1157+
1158+
#[cfg(test)]
1159+
mod tests {
1160+
use std::time::Duration;
1161+
1162+
use crate::transport::Server;
1163+
1164+
#[test]
1165+
fn server_tcp_defaults() {
1166+
const EXAMPLE_TCP_KEEPALIVE: Duration = Duration::from_secs(10);
1167+
1168+
// Using ::builder() or ::default() should do the same thing
1169+
let server_via_builder = Server::builder();
1170+
assert_eq!(server_via_builder.tcp_nodelay, true);
1171+
assert_eq!(server_via_builder.tcp_keepalive, None);
1172+
let server_via_default = Server::default();
1173+
assert_eq!(server_via_default.tcp_nodelay, true);
1174+
assert_eq!(server_via_default.tcp_keepalive, None);
1175+
1176+
// overriding should be possible
1177+
let server_via_builder = Server::builder()
1178+
.tcp_nodelay(false)
1179+
.tcp_keepalive(Some(EXAMPLE_TCP_KEEPALIVE));
1180+
assert_eq!(server_via_builder.tcp_nodelay, false);
1181+
assert_eq!(
1182+
server_via_builder.tcp_keepalive,
1183+
Some(EXAMPLE_TCP_KEEPALIVE)
1184+
);
1185+
}
1186+
}

0 commit comments

Comments
 (0)