Skip to content

Commit

Permalink
Don't special case stream frames for opportunistic ACKing
Browse files Browse the repository at this point in the history
Summary: This was added to not bundle ACKs with stream frames. Don't special case those and also disabling opportunistic ACKing for all write reasons.

Reviewed By: jbeshay

Differential Revision: D66514392

fbshipit-source-id: f2657a5c06ea8ae37b8c8eacd04c5a3b8ac75390
  • Loading branch information
Matt Joras authored and facebook-github-bot committed Nov 27, 2024
1 parent 2322ee8 commit 058f5db
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 4 deletions.
6 changes: 2 additions & 4 deletions quic/api/QuicTransportFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,9 @@ WriteQuicDataResult writeQuicDataToSocketImpl(
.pingFrames()
.datagramFrames()
.immediateAckFrames();
// Only add ACK frames if we need to send an ACK, or if the write reason isn't
// just streams.
// Only add ACK frames if we need to send an ACK.
if (connection.transportSettings.opportunisticAcking ||
toWriteAppDataAcks(connection) ||
(hasNonAckDataToWrite(connection) != WriteDataReason::STREAM)) {
toWriteAppDataAcks(connection)) {
schedulerBuilder.ackFrames();
}
if (!exceptCryptoStream) {
Expand Down
38 changes: 38 additions & 0 deletions quic/api/test/QuicTransportTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2084,6 +2084,44 @@ TEST_F(QuicTransportTest, NoWritePendingAckIfHavingData) {
EXPECT_EQ(3, ackState.numNonRxPacketsRecvd);
}

TEST_F(QuicTransportTest, NoWritePendingAckIfHavingDataNonStream) {
auto& conn = transport_->getConnectionState();
conn.transportSettings.opportunisticAcking = false;
auto streamId = transport_->createBidirectionalStream().value();
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(testing::WithArgs<1, 2>(Invoke(getTotalIovecLen)));
// We should write acks if there is data pending
conn.streamManager->queueWindowUpdate(streamId);
transport_->read(streamId, 0);
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, none);

auto pnSpace = packet.header.getPacketNumberSpace();
auto ackState = getAckState(conn, pnSpace);
EXPECT_EQ(ackState.largestAckScheduled, none);
EXPECT_FALSE(ackState.needsToSendAckImmediately);
EXPECT_EQ(3, ackState.numNonRxPacketsRecvd);
}

TEST_F(QuicTransportTest, RstStream) {
auto streamId = transport_->createBidirectionalStream().value();
EXPECT_CALL(*socket_, write(_, _, _))
Expand Down

0 comments on commit 058f5db

Please sign in to comment.