-
-
Save WesleyRosenblum/6e74c9944e3e27405d047bdf669e62c2 to your computer and use it in GitHub Desktop.
Under utilized
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
impl CubicCongestionController { | |
pub fn new(max_datagram_size: u16) -> Self { | |
Self { | |
cubic: Cubic::new(max_datagram_size), | |
slow_start: HybridSlowStart::new(max_datagram_size), | |
max_datagram_size, | |
congestion_window: CubicCongestionController::initial_window(max_datagram_size) as f32, | |
state: SlowStart, | |
bytes_in_flight: Counter::new(0), | |
time_of_last_sent_packet: None, | |
is_under_utilized: true, | |
} | |
} | |
fn on_packet_sent(&mut self, time_sent: Timestamp, bytes_sent: usize) { | |
self.bytes_in_flight | |
.try_add(bytes_sent) | |
.expect("bytes sent should not exceed u32::MAX"); | |
self.is_under_utilized = self.is_congestion_window_under_utilized(); | |
if self.is_under_utilized { | |
if let CongestionAvoidance(ref mut avoidance_start_time) = self.state { | |
//= https://tools.ietf.org/rfc/rfc8312#5.8 | |
//# CUBIC does not raise its congestion window size if the flow is | |
//# currently limited by the application instead of the congestion | |
//# window. In case of long periods when cwnd has not been updated due | |
//# to the application rate limit, such as idle periods, t in Eq. 1 MUST | |
//# NOT include these periods; otherwise, W_cubic(t) might be very high | |
//# after restarting from these periods. | |
// Since we are application limited, we shift the start time of CongestionAvoidance | |
// by the app limited duration, to avoid including that duration in W_cubic(t). | |
let last_time_sent = self.time_of_last_sent_packet.unwrap_or(time_sent); | |
// Use the later of the last time sent and the avoidance start time to not count | |
// the app limited time spent prior to entering congestion avoidance. | |
let app_limited_duration = time_sent - last_time_sent.max(*avoidance_start_time); | |
*avoidance_start_time += app_limited_duration; | |
} | |
} | |
if let Recovery(recovery_start_time, RequiresTransmission) = self.state { | |
// A packet has been sent since we entered recovery (fast retransmission) | |
// so flip the state back to idle. | |
self.state = Recovery(recovery_start_time, Idle); | |
} | |
self.time_of_last_sent_packet = Some(time_sent); | |
} | |
fn on_packet_ack( | |
&mut self, | |
largest_acked_time_sent: Timestamp, | |
sent_bytes: usize, | |
rtt_estimator: &RTTEstimator, | |
ack_receive_time: Timestamp, | |
) { | |
self.bytes_in_flight | |
.try_sub(sent_bytes) | |
.expect("sent bytes should not exceed u32::MAX"); | |
if self.is_under_utilized { | |
//= https://tools.ietf.org/id/draft-ietf-quic-recovery-32.txt#7.8 | |
//# When bytes in flight is smaller than the congestion window and | |
//# sending is not pacing limited, the congestion window is under- | |
//# utilized. When this occurs, the congestion window SHOULD NOT be | |
//# increased in either slow start or congestion avoidance. This can | |
//# happen due to insufficient application data or flow control limits. | |
return; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment