Skip to content

Commit

Permalink
Optimize pacing for acknowledgement packets (#417)
Browse files Browse the repository at this point in the history
  • Loading branch information
iyangsj authored Oct 25, 2024
1 parent 50df594 commit 59e18d3
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 9 deletions.
5 changes: 5 additions & 0 deletions src/connection/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1786,6 +1786,7 @@ impl Connection {
in_flight: write_status.in_flight,
has_data: write_status.has_data,
pmtu_probe: write_status.is_pmtu_probe,
pacing: write_status.pacing,
frames: write_status.frames,
rate_sample_state: Default::default(),
buffer_flags: write_status.buffer_flags,
Expand Down Expand Up @@ -1930,6 +1931,7 @@ impl Connection {
if !st.is_probe && !r.can_send() {
return Err(Error::Done);
}
st.pacing = true;

// Write PMTU probe frames
// Note: To probe the path MTU, the write size will exceed `left` but
Expand Down Expand Up @@ -4483,6 +4485,9 @@ struct FrameWriteStatus {
/// Whether it is a PMTU probe packet
is_pmtu_probe: bool,

/// Whether it consumes the pacer's tokens
pacing: bool,

/// Packet overhead (i.e. packet header and crypto overhead) in bytes
overhead: usize,

Expand Down
37 changes: 28 additions & 9 deletions src/connection/recovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ impl Recovery {
) {
let in_flight = pkt.in_flight;
let ack_eliciting = pkt.ack_eliciting;
let pacing = pkt.pacing;
let sent_size = pkt.sent_size;

pkt.time_sent = now;
Expand Down Expand Up @@ -218,7 +219,9 @@ impl Recovery {
}

// Update pacing tokens number.
self.pacer.on_sent(sent_size as u64);
if pacing {
self.pacer.on_sent(sent_size as u64);
}
}

/// Handle packet acknowledgment event.
Expand Down Expand Up @@ -845,8 +848,29 @@ impl Recovery {

/// Check whether this path can still send packets.
pub(crate) fn can_send(&mut self) -> bool {
self.bytes_in_flight < self.congestion.congestion_window() as usize
&& (!self.pacer.enabled() || self.can_pacing())
// Check congestion controller
if self.bytes_in_flight >= self.congestion.congestion_window() as usize {
trace!(
"{} sending is limited by congestion controller, inflight {}, window {}",
self.trace_id,
self.bytes_in_flight,
self.congestion.congestion_window()
);
return false;
}

// Check pacer
if self.pacer.enabled() && !self.can_pacing() {
trace!(
"{} sending is limited by pacer, pacing timer {:?}",
self.trace_id,
self.pacer_timer
.map(|t| t.saturating_duration_since(Instant::now()))
);
return false;
}

true
}

fn can_pacing(&mut self) -> bool {
Expand All @@ -865,12 +889,7 @@ impl Recovery {
);
}

if self.pacer_timer.is_none() {
true
} else {
trace!("{} pacing timer is {:?}", self.trace_id, self.pacer_timer);
false
}
self.pacer_timer.is_none()
}

/// Update statistics for the packet sent event
Expand Down
4 changes: 4 additions & 0 deletions src/connection/space.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,9 @@ pub struct SentPacket {
/// Whether it is a PMUT probe packet
pub pmtu_probe: bool,

/// Whether it consumes the pacer's tokens
pub pacing: bool,

/// The number of bytes sent in the packet, not including UDP or IP overhead,
/// but including QUIC framing overhead.
pub sent_size: usize,
Expand All @@ -393,6 +396,7 @@ impl Default for SentPacket {
in_flight: false,
has_data: false,
pmtu_probe: false,
pacing: false,
sent_size: 0,
rate_sample_state: RateSamplePacketState::default(),
buffer_flags: BufferFlags::default(),
Expand Down

0 comments on commit 59e18d3

Please sign in to comment.