Add SendAlgorithmInterface::HasGoodBandwidthEstimateForResumption() to be used to gauge if there is a good enough bandwidth estimate for bandwidth resumption.
PiperOrigin-RevId: 440093645
diff --git a/quic/core/congestion_control/bbr2_sender.cc b/quic/core/congestion_control/bbr2_sender.cc
index 240c333..e60f998 100644
--- a/quic/core/congestion_control/bbr2_sender.cc
+++ b/quic/core/congestion_control/bbr2_sender.cc
@@ -333,6 +333,9 @@
congestion_event);
last_sample_is_app_limited_ =
congestion_event.last_packet_send_state.is_app_limited;
+ if (!last_sample_is_app_limited_) {
+ has_non_app_limited_sample_ = true;
+ }
if (congestion_event.bytes_in_flight == 0 &&
params().avoid_unnecessary_probe_rtt) {
OnEnterQuiescence(event_time);
diff --git a/quic/core/congestion_control/bbr2_sender.h b/quic/core/congestion_control/bbr2_sender.h
index a0b5199..1a2f9d2 100644
--- a/quic/core/congestion_control/bbr2_sender.h
+++ b/quic/core/congestion_control/bbr2_sender.h
@@ -83,6 +83,10 @@
return model_.BandwidthEstimate();
}
+ bool HasGoodBandwidthEstimateForResumption() const override {
+ return has_non_app_limited_sample_;
+ }
+
QuicByteCount GetCongestionWindow() const override;
QuicByteCount GetSlowStartThreshold() const override { return 0; }
@@ -198,6 +202,8 @@
Bbr2ProbeBwMode probe_bw_;
Bbr2ProbeRttMode probe_rtt_;
+ bool has_non_app_limited_sample_ = false;
+
// Debug only.
bool last_sample_is_app_limited_;
diff --git a/quic/core/congestion_control/bbr2_simulator_test.cc b/quic/core/congestion_control/bbr2_simulator_test.cc
index 95e6da8..0a3a7e7 100644
--- a/quic/core/congestion_control/bbr2_simulator_test.cc
+++ b/quic/core/congestion_control/bbr2_simulator_test.cc
@@ -1225,11 +1225,14 @@
DefaultTopologyParams params;
CreateNetwork(params);
+ EXPECT_FALSE(sender_->HasGoodBandwidthEstimateForResumption());
DriveOutOfStartup(params);
EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+ EXPECT_TRUE(sender_->HasGoodBandwidthEstimateForResumption());
SendBursts(params, 20, 512, QuicTime::Delta::FromSeconds(3));
EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
+ EXPECT_TRUE(sender_->HasGoodBandwidthEstimateForResumption());
EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
sender_->ExportDebugState().bandwidth_hi, 0.01f);
}
diff --git a/quic/core/congestion_control/bbr_sender.h b/quic/core/congestion_control/bbr_sender.h
index ea6410f..49b3a34 100644
--- a/quic/core/congestion_control/bbr_sender.h
+++ b/quic/core/congestion_control/bbr_sender.h
@@ -127,6 +127,9 @@
bool CanSend(QuicByteCount bytes_in_flight) override;
QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override;
QuicBandwidth BandwidthEstimate() const override;
+ bool HasGoodBandwidthEstimateForResumption() const override {
+ return has_non_app_limited_sample();
+ }
QuicByteCount GetCongestionWindow() const override;
QuicByteCount GetSlowStartThreshold() const override;
CongestionControlType GetCongestionControlType() const override;
diff --git a/quic/core/congestion_control/bbr_sender_test.cc b/quic/core/congestion_control/bbr_sender_test.cc
index 98a95ec..3746d9e 100644
--- a/quic/core/congestion_control/bbr_sender_test.cc
+++ b/quic/core/congestion_control/bbr_sender_test.cc
@@ -590,12 +590,15 @@
// small bursts of data after sending continuously for a while.
TEST_F(BbrSenderTest, ApplicationLimitedBursts) {
CreateDefaultSetup();
+ EXPECT_FALSE(sender_->HasGoodBandwidthEstimateForResumption());
DriveOutOfStartup();
EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+ EXPECT_TRUE(sender_->HasGoodBandwidthEstimateForResumption());
SendBursts(20, 512, QuicTime::Delta::FromSeconds(3));
EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
+ EXPECT_TRUE(sender_->HasGoodBandwidthEstimateForResumption());
EXPECT_APPROX_EQ(kTestLinkBandwidth,
sender_->ExportDebugState().max_bandwidth, 0.01f);
}
diff --git a/quic/core/congestion_control/send_algorithm_interface.h b/quic/core/congestion_control/send_algorithm_interface.h
index 3135f21..e35b739 100644
--- a/quic/core/congestion_control/send_algorithm_interface.h
+++ b/quic/core/congestion_control/send_algorithm_interface.h
@@ -122,6 +122,9 @@
// Returns 0 when it does not have an estimate.
virtual QuicBandwidth BandwidthEstimate() const = 0;
+ // Whether BandwidthEstimate returns a good measurement for resumption.
+ virtual bool HasGoodBandwidthEstimateForResumption() const = 0;
+
// Returns the size of the current congestion window in bytes. Note, this is
// not the *available* window. Some send algorithms may not use a congestion
// window and will return 0.
diff --git a/quic/core/congestion_control/tcp_cubic_sender_bytes.h b/quic/core/congestion_control/tcp_cubic_sender_bytes.h
index be4d2b2..8f52a6a 100644
--- a/quic/core/congestion_control/tcp_cubic_sender_bytes.h
+++ b/quic/core/congestion_control/tcp_cubic_sender_bytes.h
@@ -68,6 +68,7 @@
bool CanSend(QuicByteCount bytes_in_flight) override;
QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override;
QuicBandwidth BandwidthEstimate() const override;
+ bool HasGoodBandwidthEstimateForResumption() const override { return false; }
QuicByteCount GetCongestionWindow() const override;
QuicByteCount GetSlowStartThreshold() const override;
CongestionControlType GetCongestionControlType() const override;
diff --git a/quic/test_tools/quic_test_utils.h b/quic/test_tools/quic_test_utils.h
index 7e474b5..ab5a8e7 100644
--- a/quic/test_tools/quic_test_utils.h
+++ b/quic/test_tools/quic_test_utils.h
@@ -1189,6 +1189,8 @@
MOCK_METHOD(bool, CanSend, (QuicByteCount), (override));
MOCK_METHOD(QuicBandwidth, PacingRate, (QuicByteCount), (const, override));
MOCK_METHOD(QuicBandwidth, BandwidthEstimate, (), (const, override));
+ MOCK_METHOD(bool, HasGoodBandwidthEstimateForResumption, (),
+ (const, override));
MOCK_METHOD(QuicByteCount, GetCongestionWindow, (), (const, override));
MOCK_METHOD(std::string, GetDebugState, (), (const, override));
MOCK_METHOD(bool, InSlowStart, (), (const, override));