Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion proxygen/lib/http/webtransport/QuicWtSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,12 @@ void QuicWtSessionBase::StreamManagerCallback::eventsAvailableImpl() noexcept {
if (streamData.fin) {
sock->setStopSendingCallback(streamId, nullptr);
} else if (isWtStreamEgressFcBlocked(sess.sm_, *wh)) {
sess.quicSocket_->notifyPendingWriteOnStream(streamId, &sess);
// The cached window may lag the peer's MAX_STREAM_DATA; refreshing it
// here saves a loop iteration through notifyPendingWriteOnStream.
grantMaxData(*sock, sess.sm_, *wh);
if (isWtStreamEgressFcBlocked(sess.sm_, *wh)) {
sess.quicSocket_->notifyPendingWriteOnStream(streamId, &sess);
}
}
}
}
Expand Down
21 changes: 21 additions & 0 deletions proxygen/lib/http/webtransport/test/QuicWtSessionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,27 @@ TEST_F(QuicWtSessionTest, WriteFlowControlBlocked) {
EXPECT_TRUE(stream.writeEOF);
}

TEST_F(QuicWtSessionTest, WriteRefreshesStaleFlowControl) {
auto handle = session_->createUniStream();
ASSERT_TRUE(handle.hasValue());
const auto id = handle.value()->getID();
socketDriver_.setConnectionFlowControlWindow(
std::numeric_limits<uint64_t>::max());

// Peer raised MAX_STREAM_DATA after creation; the cached window is stale.
constexpr size_t kDataLength = 65'537;
socketDriver_.setStreamFlowControlWindow(id, kDataLength);

handle.value()->writeStreamData(
folly::IOBuf::copyBuffer(std::string(kDataLength, 'a')), true, nullptr);
eventBase_.loopOnce();

auto& stream = socketDriver_.streams_[id];
EXPECT_EQ(stream.writeBuf.chainLength(), kDataLength);
EXPECT_TRUE(stream.writeEOF);
EXPECT_EQ(stream.pendingWriteCb.stream, nullptr);
}

/**
* Unsure if the following is possible in production (i.e. QuicTransportBase) --
* but it tests when a ::writeChain fails without a prior ::readError or
Expand Down
Loading