Skip to content

Commit 9bf5d27

Browse files
committed
FramedTcp handling the nagle algorithm to improve the performance
1 parent de9bf83 commit 9bf5d27

File tree

3 files changed

+19
-3
lines changed

3 files changed

+19
-3
lines changed

benches/latency.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,10 @@ fn latency_by_native_framed_tcp(c: &mut Criterion) {
107107

108108
b.iter(|| {
109109
let encoded_size = encoding::encode_size(&[0xFF], &mut framming);
110+
sender.set_nodelay(false).ok();
110111
sender.write(&encoded_size).unwrap();
111112
sender.write(&[0xFF]).unwrap();
113+
sender.set_nodelay(true).ok();
112114

113115
let mut message_received = false;
114116
while !message_received {

examples/throughput/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,10 @@ fn throughput_native_framed_tcp(packet_size: usize) {
193193
let start_time = Instant::now();
194194
while total_sent < EXPECTED_BYTES {
195195
let encoded_size = encoding::encode_size(&message, &mut framming);
196+
sender.set_nodelay(false).ok();
196197
sender.write(&encoded_size).unwrap();
197198
sender.write(&message).unwrap();
199+
sender.set_nodelay(true).ok();
198200
total_sent += message.len();
199201
}
200202
start_time

src/adapters/framed_tcp.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,21 @@ impl Remote for RemoteResource {
8888
let mut buf = [0; MAX_ENCODED_SIZE]; // used to avoid a heap allocation
8989
let encoded_size = encoding::encode_size(data, &mut buf);
9090

91+
let stream = &self.stream;
92+
// We want to send the message as a whole whatever it can be possible.
93+
// In this protocol, sending few bytes than the message has no sense and adds latency:
94+
// by the network sending small chunks, and by the receiver allocating memory to decode them.
95+
// If the target is throughput, use TCP instead.
96+
stream.set_nodelay(false).ok();
97+
9198
let mut total_bytes_sent = 0;
9299
let total_bytes = encoded_size.len() + data.len();
93-
loop {
100+
let status = loop {
94101
let data_to_send = match total_bytes_sent < encoded_size.len() {
95102
true => &encoded_size[total_bytes_sent..],
96103
false => &data[total_bytes_sent - encoded_size.len()..],
97104
};
98105

99-
let stream = &self.stream;
100106
match stream.deref().write(data_to_send) {
101107
Ok(bytes_sent) => {
102108
total_bytes_sent += bytes_sent;
@@ -110,7 +116,13 @@ impl Remote for RemoteResource {
110116
break SendStatus::ResourceNotFound // should not happen
111117
}
112118
}
113-
}
119+
};
120+
121+
// We have already the entire message in the OS buffer, send now, not wait for the next one.
122+
// The message in this protocol has an information meanless.
123+
// The user can process already this unit of data. Do not wait for other possible message.
124+
stream.set_nodelay(true).ok();
125+
status
114126
}
115127
}
116128

0 commit comments

Comments
 (0)