gfe-relnote: Ensure the ACK delay is at least the alarm granularity(1ms) when ACK decimation is enabled. Protected by gfe2_reloadable_flag_quic_ack_delay_alarm_granularity.
PiperOrigin-RevId: 290179167
Change-Id: I71fdac347c6e8637a481280b3aa9bb40a96c22df
diff --git a/quic/core/quic_received_packet_manager.cc b/quic/core/quic_received_packet_manager.cc
index 86b060e..9e33ea4 100644
--- a/quic/core/quic_received_packet_manager.cc
+++ b/quic/core/quic_received_packet_manager.cc
@@ -245,6 +245,10 @@
// before sending an ack.
QuicTime::Delta ack_delay = std::min(
local_max_ack_delay_, rtt_stats->min_rtt() * ack_decimation_delay_);
+ if (GetQuicReloadableFlag(quic_ack_delay_alarm_granularity)) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_ack_delay_alarm_granularity);
+ ack_delay = std::max(ack_delay, kAlarmGranularity);
+ }
if (fast_ack_after_quiescence_ && now - time_of_previous_received_packet_ >
rtt_stats->SmoothedOrInitialRtt()) {
// Ack the first packet out of queiscence faster, because QUIC does
diff --git a/quic/core/quic_received_packet_manager_test.cc b/quic/core/quic_received_packet_manager_test.cc
index fd27663..7355847 100644
--- a/quic/core/quic_received_packet_manager_test.cc
+++ b/quic/core/quic_received_packet_manager_test.cc
@@ -11,7 +11,9 @@
#include "net/third_party/quiche/src/quic/core/congestion_control/rtt_stats.h"
#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
#include "net/third_party/quiche/src/quic/core/quic_connection_stats.h"
+#include "net/third_party/quiche/src/quic/core/quic_constants.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
@@ -415,6 +417,43 @@
CheckAckTimeout(clock_.ApproximateNow());
}
+TEST_P(QuicReceivedPacketManagerTest, SendDelayedAckDecimationMin1ms) {
+ if (!GetQuicReloadableFlag(quic_ack_delay_alarm_granularity)) {
+ return;
+ }
+ EXPECT_FALSE(HasPendingAck());
+ QuicReceivedPacketManagerPeer::SetAckMode(&received_manager_, ACK_DECIMATION);
+ // Seed the min_rtt with a kAlarmGranularity signal.
+ rtt_stats_.UpdateRtt(kAlarmGranularity, QuicTime::Delta::Zero(),
+ clock_.ApproximateNow());
+ // The ack time should be based on kAlarmGranularity, since the RTT is 1ms.
+ QuicTime ack_time = clock_.ApproximateNow() + kAlarmGranularity;
+
+ // Process all the packets in order so there aren't missing packets.
+ uint64_t kFirstDecimatedPacket = 101;
+ for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
+ RecordPacketReceipt(i, clock_.ApproximateNow());
+ MaybeUpdateAckTimeout(kInstigateAck, i);
+ if (i % 2 == 0) {
+ // Ack every 2 packets by default.
+ CheckAckTimeout(clock_.ApproximateNow());
+ } else {
+ CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+ }
+ }
+
+ RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
+ MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
+ CheckAckTimeout(ack_time);
+
+ // The 10th received packet causes an ack to be sent.
+ for (uint64_t i = 1; i < 10; ++i) {
+ RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
+ MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
+ }
+ CheckAckTimeout(clock_.ApproximateNow());
+}
+
TEST_P(QuicReceivedPacketManagerTest,
SendDelayedAckAckDecimationAfterQuiescence) {
EXPECT_FALSE(HasPendingAck());