1
0
mirror of https://github.com/facebookincubator/mvfst.git synced 2025-08-06 22:22:38 +03:00

Application limited time in packet metadata

Summary:
Track the total (cumulative) amount of time that the connection has been application limited and store this information in `OutstandingPacketMetadata`. If this value is the same for two `OutstandingPacketMetadata` then we know that the transport did not become application limited between when those two packets were sent (or, less likely, the transport was application limited for less than one microsecond given the microsecond resolution of the timestamp).

We store the amount of time spent application limited instead of a count of the number of application limited events because the implications of being application limited are time dependent.

Tests show that we need to be able to inject a mockable clock. That's been an issue for some time; will work on in a subsequent diff.

Differential Revision: D41714879

fbshipit-source-id: 9fd4fe321d85639dc9fb5c2cd51713c481cbeb22
This commit is contained in:
Brandon Schlinker
2022-12-08 18:55:22 -08:00
committed by Facebook GitHub Bot
parent 9ddbed6d5e
commit eb3009484a
7 changed files with 380 additions and 14 deletions

View File

@@ -1520,6 +1520,102 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionWithBytesStats) {
->lastAckedPacketInfo->totalBytesAcked);
}
TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionWithAppLimitedStats) {
auto conn = createConn();
auto stream = conn->streamManager->createNextBidirectionalStream().value();
auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
writeDataToQuicStream(
*stream, folly::IOBuf::copyBuffer("Im gonna cut your hair."), true);
WriteStreamFrame writeStreamFrame(stream->id, 0, 5, false);
packet.packet.frames.push_back(std::move(writeStreamFrame));
// connections should start off being app limited
EXPECT_TRUE(conn->appLimitedTracker.isAppLimited());
// mark ourselves as not app limited, verify that total app limited time > 0,
// verify that successive calls to getTotalAppLimitedTime yield same value
conn->appLimitedTracker.setNotAppLimited();
EXPECT_LT(0us, conn->appLimitedTracker.getTotalAppLimitedTime());
EXPECT_EQ(
conn->appLimitedTracker.getTotalAppLimitedTime(),
conn->appLimitedTracker.getTotalAppLimitedTime());
// record the packet as having been sent
updateConnection(
*conn,
folly::none,
packet.packet,
TimePoint(),
555,
500,
false /* isDSRPacket */);
// should have the current app limited time recorded in metadata
EXPECT_EQ(
conn->appLimitedTracker.getTotalAppLimitedTime(),
getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
->metadata.totalAppLimitedTimeUsecs);
}
TEST_F(
QuicTransportFunctionsTest,
TestUpdateConnectionWithAppLimitedStats_MultipleTransitions) {
auto conn = createConn();
auto stream = conn->streamManager->createNextBidirectionalStream().value();
auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
writeDataToQuicStream(
*stream, folly::IOBuf::copyBuffer("Im gonna cut your hair."), true);
WriteStreamFrame writeStreamFrame(stream->id, 0, 5, false);
packet.packet.frames.push_back(std::move(writeStreamFrame));
// connections should start off being app limited
EXPECT_TRUE(conn->appLimitedTracker.isAppLimited());
{
// successive calls should yield different measurements
const auto time1 = conn->appLimitedTracker.getTotalAppLimitedTime();
std::this_thread::sleep_for(10ms);
const auto time2 = conn->appLimitedTracker.getTotalAppLimitedTime();
EXPECT_NE(time1, time2);
}
// mark ourselves as not app limited, verify that total app limited time > 0,
// verify that successive calls to getTotalAppLimitedTime yield same value
conn->appLimitedTracker.setNotAppLimited();
EXPECT_LT(0us, conn->appLimitedTracker.getTotalAppLimitedTime());
EXPECT_EQ(
conn->appLimitedTracker.getTotalAppLimitedTime(),
conn->appLimitedTracker.getTotalAppLimitedTime());
const auto appLimitedTime1 = conn->appLimitedTracker.getTotalAppLimitedTime();
// become app limited for at least 10ms, then repeat the above
conn->appLimitedTracker.setAppLimited();
std::this_thread::sleep_for(10ms);
conn->appLimitedTracker.setNotAppLimited();
EXPECT_LE(
appLimitedTime1 + 10ms, conn->appLimitedTracker.getTotalAppLimitedTime());
EXPECT_EQ(
conn->appLimitedTracker.getTotalAppLimitedTime(),
conn->appLimitedTracker.getTotalAppLimitedTime());
// record the packet as having been sent
updateConnection(
*conn,
folly::none,
packet.packet,
TimePoint(),
555,
500,
false /* isDSRPacket */);
// should have the current app limited time recorded in metadata
EXPECT_EQ(
conn->appLimitedTracker.getTotalAppLimitedTime(),
getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
->metadata.totalAppLimitedTimeUsecs);
}
TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionWithCloneResult) {
auto conn = createConn();
conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);