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

Add TransportSetting and knob for default priority.

Summary: Allows the default stream priority (which also means scheduling policy) to be set via TransportSettings.

Reviewed By: jbeshay, hanidamlaj

Differential Revision: D45881729

fbshipit-source-id: fcb72022cd6eac2f1dafc55173d5a46a72a95dbc
This commit is contained in:
Matt Joras
2023-05-18 13:51:53 -07:00
committed by Facebook GitHub Bot
parent 1c6e089f9e
commit b89882a772
6 changed files with 111 additions and 2 deletions

View File

@@ -167,7 +167,8 @@ BETTER_ENUM(
// Controls whether to fire write loops early when pacing
FIRE_LOOP_EARLY = 0x10001,
// Controls the timer tick used for pacing
PACING_TIMER_TICK = 0x10002)
PACING_TIMER_TICK = 0x10002,
DEFAULT_STREAM_PRIORITY = 0x10003)
enum class FrameType : uint64_t {
PADDING = 0x00,

View File

@@ -1430,6 +1430,73 @@ TEST_F(QuicPacketSchedulerTest, StreamFrameSchedulerSequential) {
EXPECT_EQ(*frames[2].asWriteStreamFrame(), f3);
}
TEST_F(QuicPacketSchedulerTest, StreamFrameSchedulerSequentialDefault) {
QuicClientConnectionState conn(
FizzClientQuicHandshakeContext::Builder().build());
conn.streamManager->setMaxLocalBidirectionalStreams(10);
conn.flowControlState.peerAdvertisedMaxOffset = 100000;
conn.flowControlState.peerAdvertisedInitialMaxStreamOffsetBidiRemote = 100000;
conn.transportSettings.defaultPriority = Priority(0, false);
auto connId = getTestConnectionId();
StreamFrameScheduler scheduler(conn);
ShortHeader shortHeader1(
ProtectionType::KeyPhaseZero,
connId,
getNextPacketNum(conn, PacketNumberSpace::AppData));
RegularQuicPacketBuilder builder1(
conn.udpSendPacketLen,
std::move(shortHeader1),
conn.ackStates.appDataAckState.largestAckedByPeer.value_or(0));
auto stream1 =
conn.streamManager->createNextBidirectionalStream().value()->id;
auto stream2 =
conn.streamManager->createNextBidirectionalStream().value()->id;
auto stream3 =
conn.streamManager->createNextBidirectionalStream().value()->id;
auto largeBuf = folly::IOBuf::createChain(conn.udpSendPacketLen * 2, 4096);
auto curBuf = largeBuf.get();
do {
curBuf->append(curBuf->capacity());
curBuf = curBuf->next();
} while (curBuf != largeBuf.get());
auto chainLen = largeBuf->computeChainDataLength();
writeDataToQuicStream(
*conn.streamManager->findStream(stream1), std::move(largeBuf), false);
writeDataToQuicStream(
*conn.streamManager->findStream(stream2),
folly::IOBuf::copyBuffer("some data"),
false);
writeDataToQuicStream(
*conn.streamManager->findStream(stream3),
folly::IOBuf::copyBuffer("some data"),
false);
// The default is to wraparound initially.
scheduler.writeStreams(builder1);
EXPECT_EQ(
conn.streamManager->writableStreams().getNextScheduledStream(
Priority(0, false)),
stream1);
// Should write frames for stream1, stream2, stream3, in that order.
NiceMock<MockQuicPacketBuilder> builder2;
EXPECT_CALL(builder2, remainingSpaceInPkt()).WillRepeatedly(Return(4096));
EXPECT_CALL(builder2, appendFrame(_)).WillRepeatedly(Invoke([&](auto f) {
builder2.frames_.push_back(f);
}));
scheduler.writeStreams(builder2);
auto& frames = builder2.frames_;
ASSERT_EQ(frames.size(), 3);
WriteStreamFrame f1(stream1, 0, chainLen, false);
WriteStreamFrame f2(stream2, 0, 9, false);
WriteStreamFrame f3(stream3, 0, 9, false);
ASSERT_TRUE(frames[0].asWriteStreamFrame());
EXPECT_EQ(*frames[0].asWriteStreamFrame(), f1);
ASSERT_TRUE(frames[1].asWriteStreamFrame());
EXPECT_EQ(*frames[1].asWriteStreamFrame(), f2);
ASSERT_TRUE(frames[2].asWriteStreamFrame());
EXPECT_EQ(*frames[2].asWriteStreamFrame(), f3);
}
TEST_F(QuicPacketSchedulerTest, StreamFrameSchedulerRoundRobinControl) {
QuicClientConnectionState conn(
FizzClientQuicHandshakeContext::Builder().build());

View File

@@ -1046,6 +1046,31 @@ void QuicServerTransport::registerAllTransportKnobParamHandlers() {
std::chrono::microseconds(val);
VLOG(3) << "PACING_TIMER_TICK KnobParam received: " << val;
});
registerTransportKnobParamHandler(
static_cast<uint64_t>(TransportKnobParamId::DEFAULT_STREAM_PRIORITY),
[](QuicServerTransport* serverTransport, TransportKnobParam::Val value) {
CHECK(serverTransport);
auto val = std::get<std::string>(value);
auto serverConn = serverTransport->serverConn_;
uint8_t level;
bool incremental;
bool parseSuccess = false;
try {
parseSuccess = folly::split(",", val, level, incremental);
} catch (std::exception&) {
parseSuccess = false;
}
if (!parseSuccess) {
auto errMsg = fmt::format(
"Received invalid KnobParam for DEFAULT_STREAM_PRIORITY: {}",
val);
VLOG(3) << errMsg;
throw std::runtime_error(errMsg);
}
serverConn->transportSettings.defaultPriority =
Priority(level, incremental);
VLOG(3) << "DEFAULT_STREAM_PRIORITY KnobParam received: " << val;
});
}
QuicConnectionStats QuicServerTransport::getConnectionsStats() const {

View File

@@ -4825,7 +4825,18 @@ TEST_F(QuicServerTransportTest, TestAckFrequencyPolicyKnobHandler) {
server->handleKnobParams(
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
"1,3,1,1"}});
EXPECT_FALSE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
server->handleKnobParams(
{{static_cast<uint64_t>(TransportKnobParamId::DEFAULT_STREAM_PRIORITY),
"1,1"}});
EXPECT_EQ(server->getTransportSettings().defaultPriority, Priority(1, true));
server->handleKnobParams(
{{static_cast<uint64_t>(TransportKnobParamId::DEFAULT_STREAM_PRIORITY),
"4,0"}});
EXPECT_EQ(server->getTransportSettings().defaultPriority, Priority(4, false));
server->handleKnobParams(
{{static_cast<uint64_t>(TransportKnobParamId::DEFAULT_STREAM_PRIORITY),
"4,0,10"}});
EXPECT_EQ(server->getTransportSettings().defaultPriority, Priority(4, false));
}
TEST_F(QuicServerTransportTest, TestSetMaxPacingRateLifecycle) {

View File

@@ -38,6 +38,7 @@ QuicStreamState::QuicStreamState(StreamId idIn, QuicConnectionStateBase& connIn)
sendState = StreamSendState::Invalid;
}
}
priority = connIn.transportSettings.defaultPriority;
}
QuicStreamState::QuicStreamState(

View File

@@ -9,6 +9,7 @@
#include <folly/Optional.h>
#include <quic/QuicConstants.h>
#include <quic/state/QuicPriorityQueue.h>
#include <chrono>
#include <cstdint>
@@ -267,6 +268,9 @@ struct TransportSettings {
bool advertisedKnobFrameSupport{true};
bool removeStreamAfterEomCallbackUnset{false};
// The default priority to instantiate streams with.
Priority defaultPriority{kDefaultPriority};
// Local configuration for ACK receive timestamps.
//
// Determines the ACK receive timestamp configuration sent to peer,