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:
committed by
Facebook GitHub Bot
parent
1c6e089f9e
commit
b89882a772
@@ -167,7 +167,8 @@ BETTER_ENUM(
|
|||||||
// Controls whether to fire write loops early when pacing
|
// Controls whether to fire write loops early when pacing
|
||||||
FIRE_LOOP_EARLY = 0x10001,
|
FIRE_LOOP_EARLY = 0x10001,
|
||||||
// Controls the timer tick used for pacing
|
// Controls the timer tick used for pacing
|
||||||
PACING_TIMER_TICK = 0x10002)
|
PACING_TIMER_TICK = 0x10002,
|
||||||
|
DEFAULT_STREAM_PRIORITY = 0x10003)
|
||||||
|
|
||||||
enum class FrameType : uint64_t {
|
enum class FrameType : uint64_t {
|
||||||
PADDING = 0x00,
|
PADDING = 0x00,
|
||||||
|
@@ -1430,6 +1430,73 @@ TEST_F(QuicPacketSchedulerTest, StreamFrameSchedulerSequential) {
|
|||||||
EXPECT_EQ(*frames[2].asWriteStreamFrame(), f3);
|
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) {
|
TEST_F(QuicPacketSchedulerTest, StreamFrameSchedulerRoundRobinControl) {
|
||||||
QuicClientConnectionState conn(
|
QuicClientConnectionState conn(
|
||||||
FizzClientQuicHandshakeContext::Builder().build());
|
FizzClientQuicHandshakeContext::Builder().build());
|
||||||
|
@@ -1046,6 +1046,31 @@ void QuicServerTransport::registerAllTransportKnobParamHandlers() {
|
|||||||
std::chrono::microseconds(val);
|
std::chrono::microseconds(val);
|
||||||
VLOG(3) << "PACING_TIMER_TICK KnobParam received: " << 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 {
|
QuicConnectionStats QuicServerTransport::getConnectionsStats() const {
|
||||||
|
@@ -4825,7 +4825,18 @@ TEST_F(QuicServerTransportTest, TestAckFrequencyPolicyKnobHandler) {
|
|||||||
server->handleKnobParams(
|
server->handleKnobParams(
|
||||||
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
|
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
|
||||||
"1,3,1,1"}});
|
"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) {
|
TEST_F(QuicServerTransportTest, TestSetMaxPacingRateLifecycle) {
|
||||||
|
@@ -38,6 +38,7 @@ QuicStreamState::QuicStreamState(StreamId idIn, QuicConnectionStateBase& connIn)
|
|||||||
sendState = StreamSendState::Invalid;
|
sendState = StreamSendState::Invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
priority = connIn.transportSettings.defaultPriority;
|
||||||
}
|
}
|
||||||
|
|
||||||
QuicStreamState::QuicStreamState(
|
QuicStreamState::QuicStreamState(
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <folly/Optional.h>
|
#include <folly/Optional.h>
|
||||||
#include <quic/QuicConstants.h>
|
#include <quic/QuicConstants.h>
|
||||||
|
#include <quic/state/QuicPriorityQueue.h>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
@@ -267,6 +268,9 @@ struct TransportSettings {
|
|||||||
bool advertisedKnobFrameSupport{true};
|
bool advertisedKnobFrameSupport{true};
|
||||||
bool removeStreamAfterEomCallbackUnset{false};
|
bool removeStreamAfterEomCallbackUnset{false};
|
||||||
|
|
||||||
|
// The default priority to instantiate streams with.
|
||||||
|
Priority defaultPriority{kDefaultPriority};
|
||||||
|
|
||||||
// Local configuration for ACK receive timestamps.
|
// Local configuration for ACK receive timestamps.
|
||||||
//
|
//
|
||||||
// Determines the ACK receive timestamp configuration sent to peer,
|
// Determines the ACK receive timestamp configuration sent to peer,
|
||||||
|
Reference in New Issue
Block a user