From e43eb2e8b47a429e05c21e00d715430167fc5520 Mon Sep 17 00:00:00 2001 From: Brandon Schlinker Date: Thu, 16 Jul 2020 10:23:35 -0700 Subject: [PATCH] Notify connection callback when app rate limited Summary: Notify connection callback implementation when the transport becomes app rate limited - The callback implementation is not required to define a handler for this callback (not pure virtual). - D21923745 will add an instrumentation callback class that can be used to allow other components to receive this signal. I'm extending to the connection callback because the overhead seems low, and we already have the connection callback registered for `HQSession`. Reviewed By: mjoras, lnicco Differential Revision: D21923744 fbshipit-source-id: 153696aefeab82b7fd8a6bc299c011dcce479995 --- quic/api/QuicSocket.h | 5 +++++ quic/api/QuicTransportBase.cpp | 1 + quic/api/test/Mocks.h | 1 + quic/api/test/QuicTransportTest.cpp | 4 ++++ 4 files changed, 11 insertions(+) diff --git a/quic/api/QuicSocket.h b/quic/api/QuicSocket.h index 71aed841b..ff3d933d4 100644 --- a/quic/api/QuicSocket.h +++ b/quic/api/QuicSocket.h @@ -101,6 +101,11 @@ class QuicSocket { */ virtual void onUnidirectionalStreamsAvailable( uint64_t /*numStreamsAvailable*/) noexcept {} + + /** + * Invoked when transport is detected to be app rate limited. + */ + virtual void onAppRateLimited() noexcept {} }; /** diff --git a/quic/api/QuicTransportBase.cpp b/quic/api/QuicTransportBase.cpp index 9772eda3d..eefd54aed 100644 --- a/quic/api/QuicTransportBase.cpp +++ b/quic/api/QuicTransportBase.cpp @@ -2433,6 +2433,7 @@ void QuicTransportBase::writeSocketData() { currentSendBufLen < conn_->udpSendPacketLen && lossBufferEmpty && conn_->congestionController->getWritableBytes()) { conn_->congestionController->setAppLimited(); + connCallback_->onAppRateLimited(); } } } diff --git a/quic/api/test/Mocks.h b/quic/api/test/Mocks.h index 9e266a27a..aeb455423 100644 --- a/quic/api/test/Mocks.h +++ b/quic/api/test/Mocks.h @@ -117,6 +117,7 @@ class MockConnectionCallback : public QuicSocket::ConnectionCallback { , onUnidirectionalStreamsAvailable, void(uint64_t)); + GMOCK_METHOD0_(, noexcept, , onAppRateLimited, void()); }; class MockDeliveryCallback : public QuicSocket::DeliveryCallback { diff --git a/quic/api/test/QuicTransportTest.cpp b/quic/api/test/QuicTransportTest.cpp index 05ddc5b7d..383f2b909 100644 --- a/quic/api/test/QuicTransportTest.cpp +++ b/quic/api/test/QuicTransportTest.cpp @@ -280,6 +280,7 @@ TEST_F(QuicTransportTest, NotAppLimitedWithLoss) { false, nullptr); EXPECT_CALL(*rawCongestionController, setAppLimited()).Times(0); + EXPECT_CALL(connCallback_, onAppRateLimited()).Times(0); loopForWrites(); transport_->close(folly::none); } @@ -307,6 +308,7 @@ TEST_F(QuicTransportTest, NotAppLimitedWithNoWritableBytes) { false, nullptr); EXPECT_CALL(*rawCongestionController, setAppLimited()).Times(0); + EXPECT_CALL(connCallback_, onAppRateLimited()).Times(0); loopForWrites(); transport_->close(folly::none); } @@ -325,6 +327,7 @@ TEST_F(QuicTransportTest, NotAppLimitedWithLargeBuffer) { auto buf = buildRandomInputData(100 * 2000); transport_->writeChain(stream, buf->clone(), false, false, nullptr); EXPECT_CALL(*rawCongestionController, setAppLimited()).Times(0); + EXPECT_CALL(connCallback_, onAppRateLimited()).Times(0); loopForWrites(); transport_->close(folly::none); } @@ -347,6 +350,7 @@ TEST_F(QuicTransportTest, AppLimited) { false, nullptr); EXPECT_CALL(*rawCongestionController, setAppLimited()).Times(1); + EXPECT_CALL(connCallback_, onAppRateLimited()).Times(1); loopForWrites(); transport_->close(folly::none); }