mirror of
https://github.com/facebookincubator/mvfst.git
synced 2025-08-08 09:42:06 +03:00
Put opportunistic ACKing behind TransportSetting
Summary: This has been a default behavior for us for a long time. Basically, we will always include ACK frames in a burst if there's new packets to ACK. This is overall probably fine and is flexible to peer behavior such that the peer can get away with basically never sending anything ACK-eliciting. However it is not without its issues. In particular, for DSR it means that we write an excessive amount of pure ACK packets since they cannot be coalesced with a DSR burst. Make this behavior optional, such that we only include ACK frames in non-probing schedulers when we are only writing stream data. Reviewed By: kvtsoy Differential Revision: D39479149 fbshipit-source-id: 6e92d45311a3fb23750c93483b94e97dd3fdce26
This commit is contained in:
committed by
Facebook GitHub Bot
parent
74dc1b25e4
commit
3c5a34ee11
@@ -2025,6 +2025,43 @@ TEST_F(QuicTransportTest, WritePendingAckIfHavingData) {
|
||||
EXPECT_EQ(0, ackState.numNonRxPacketsRecvd);
|
||||
}
|
||||
|
||||
TEST_F(QuicTransportTest, NoWritePendingAckIfHavingData) {
|
||||
auto& conn = transport_->getConnectionState();
|
||||
conn.transportSettings.opportunisticAcking = false;
|
||||
auto streamId = transport_->createBidirectionalStream().value();
|
||||
auto buf = buildRandomInputData(20);
|
||||
PacketNum start = 10;
|
||||
PacketNum end = 15;
|
||||
addAckStatesWithCurrentTimestamps(conn.ackStates.appDataAckState, start, end);
|
||||
conn.ackStates.appDataAckState.needsToSendAckImmediately = false;
|
||||
conn.ackStates.appDataAckState.numNonRxPacketsRecvd = 3;
|
||||
EXPECT_CALL(*socket_, write(_, _)).WillOnce(Invoke(bufLength));
|
||||
// We should write acks if there is data pending
|
||||
transport_->writeChain(streamId, buf->clone(), true);
|
||||
loopForWrites();
|
||||
EXPECT_EQ(conn.outstandings.packets.size(), 1);
|
||||
auto& packet =
|
||||
getFirstOutstandingPacket(conn, PacketNumberSpace::AppData)->packet;
|
||||
EXPECT_GE(packet.frames.size(), 1);
|
||||
|
||||
bool ackFound = false;
|
||||
for (auto& frame : packet.frames) {
|
||||
auto ackFrame = frame.asWriteAckFrame();
|
||||
if (!ackFrame) {
|
||||
continue;
|
||||
}
|
||||
ackFound = true;
|
||||
}
|
||||
EXPECT_FALSE(ackFound);
|
||||
EXPECT_EQ(conn.ackStates.appDataAckState.largestAckScheduled, folly::none);
|
||||
|
||||
auto pnSpace = packet.header.getPacketNumberSpace();
|
||||
auto ackState = getAckState(conn, pnSpace);
|
||||
EXPECT_EQ(ackState.largestAckScheduled, folly::none);
|
||||
EXPECT_FALSE(ackState.needsToSendAckImmediately);
|
||||
EXPECT_EQ(3, ackState.numNonRxPacketsRecvd);
|
||||
}
|
||||
|
||||
TEST_F(QuicTransportTest, RstStream) {
|
||||
auto streamId = transport_->createBidirectionalStream().value();
|
||||
EXPECT_CALL(*socket_, write(_, _)).WillOnce(Invoke(bufLength));
|
||||
|
Reference in New Issue
Block a user