1
0
mirror of https://github.com/facebookincubator/mvfst.git synced 2025-12-04 15:42:40 +03:00

Remove DSR (Direct Server Return) from mvfst, ti/bigcache, and proxygen

Summary:
This commit completely removes the DSR (Direct Server Return) feature from the codebase. DSR was a zero-copy QUIC packet transmission mechanism that allowed backend servers to directly packetize and send data to clients, bypassing the transport layer.

Components removed:

**QUIC (fbcode/quic/)**
- Deleted quic/dsr/ directory with all DSR implementation files
- Removed BufferMeta and WriteBufferMeta from StreamData
- Removed writeBufMeta() and setDSRPacketizationRequestSender() from QuicSocket
- Removed DSR tracking from stream state (dsrSender, writeBufMeta, retransmission/loss buffers)
- Removed DSR packet tracking fields (isDSRPacket, nonDsrPacketSequenceNumber)
- Removed DSR logic from loss detection, flow control, packet scheduling
- Removed TperfDSRSender tool and DSR test infrastructure

**ti/bigcache**
- Deleted ti/bigcache/dsr/ directory (16 files: Cookie, PacketizationContext, SocketProvider, etc.)
- Removed ~1000 lines of DSR code from BigCacheCommandHandler (header/impl/inline)
- Removed XSK (AF_XDP) initialization and container management from MCBigCache.cpp
- Removed DSR RPC methods: async_eb_bigcacheGetDSR, async_eb_establishPacketizationSink, async_eb_release
- Removed getDSRBigcacheValueAsync(), createDSRDelegationRequest() from McrouterCache
- Removed DSR-specific stats namespace (dsrstats) and metrics
- Cleaned up BUCK dependencies removing quic/dsr and XSK references

**proxygen HTTP infrastructure**
- Removed allowDSR() virtual method from HTTPMessageFilter base class and 50+ filter implementations
- Removed setDSRRequestSender() interface from HTTPTransaction::Transport and HTTPSink
- Removed DSRRequestSender class and sendHeadersWithDelegate() from HTTPTransaction
- Removed BufferMeta struct and all related methods from HTTPTransaction (getBufferMeta, clearBufferMeta, etc.)
- Removed bufMeta_ member and references from HQSession::HQStreamTransportBase
- Removed isDelegated_ flag and delegated transaction checks from HTTPTransaction
- Removed cache DSR methods: canDSR(), performDSRDelegateAndScheduleCallbacks(), onDelegateSuccess(), onDelegateMiss()
- Removed DSR delegation from HTTPResponseCache and McrouterCache

**Test infrastructure fixes**
- Removed quic/dsr/test:mocks dependency from proxygen session test TARGETS
- Fixed PTM test to remove nonDsrPacketSequenceNumber field references
- Cleaned up MockQuicSocketDriver to remove DSR mock infrastructure (BufferMeta, writeBufMeta)
- Removed sendHeadersWithDelegate() from HTTPSessionMocks test helpers
- Commented out DSR-specific tests in HQDownstreamSessionTest (DelegateResponse, DelegateResponseError)
- Removed MockQuicDSRRequestSender from HQSessionMocks
- Disabled BigcacheSRPacketizer build targets (depends on removed quic/dsr infrastructure)
- Fixed WebTransportFilter, CdnFilters, and other components after removing DSR infrastructure

The codebase now exclusively uses standard QUIC stream writes through pendingWrites buffers.

Reviewed By: kvtsoy

Differential Revision: D86992558

fbshipit-source-id: a3814eaf735accdce989c45da8101aac8e8c831f
This commit is contained in:
Matt Joras
2025-11-20 22:39:59 -08:00
committed by meta-codesync[bot]
parent fa2e03c14c
commit fc66b07859
103 changed files with 246 additions and 7100 deletions

View File

@@ -532,10 +532,6 @@ quic::Expected<void, QuicError> StreamFrameScheduler::writeStreamsHelper(
do {
auto streamId = level.iterator->current();
auto stream = CHECK_NOTNULL(conn_.streamManager->findStream(streamId));
if (!stream->hasSchedulableData() && stream->hasSchedulableDsr()) {
// We hit a DSR stream
return {};
}
CHECK(stream) << "streamId=" << streamId
<< "inc=" << uint64_t(level.incremental);
auto writeResult = writeSingleStream(builder, *stream, connWritableBytes);
@@ -576,10 +572,6 @@ quic::Expected<void, QuicError> StreamFrameScheduler::writeStreamsHelper(
CHECK(id.isStreamID());
auto streamId = id.asStreamID();
auto stream = CHECK_NOTNULL(conn_.streamManager->findStream(streamId));
if (!stream->hasSchedulableData() && stream->hasSchedulableDsr()) {
// We hit a DSR stream
return {};
}
CHECK(stream) << "streamId=" << streamId;
// TODO: this is counting STREAM frame overhead against the stream itself
auto lastWriteBytes = builder.remainingSpaceInPkt();
@@ -630,7 +622,6 @@ quic::Expected<void, QuicError> StreamFrameScheduler::writeStreams(
conn_.schedulingState.nextScheduledControlStream = result.value();
}
auto* oldWriteQueue = conn_.streamManager->oldWriteQueue();
QuicStreamState* nextStream{nullptr};
if (oldWriteQueue) {
if (!oldWriteQueue->empty()) {
auto result = writeStreamsHelper(
@@ -641,8 +632,6 @@ quic::Expected<void, QuicError> StreamFrameScheduler::writeStreams(
if (!result.has_value()) {
return quic::make_unexpected(result.error());
}
auto streamId = oldWriteQueue->getNextScheduledStream();
nextStream = conn_.streamManager->findStream(streamId);
}
} else {
auto& writeQueue = conn_.streamManager->writeQueue();
@@ -655,29 +644,15 @@ quic::Expected<void, QuicError> StreamFrameScheduler::writeStreams(
if (!result.has_value()) {
return quic::make_unexpected(result.error());
}
if (!writeQueue.empty()) {
auto id = writeQueue.peekNextScheduledID();
CHECK(id.isStreamID());
nextStream = conn_.streamManager->findStream(id.asStreamID());
}
}
}
// If the next non-control stream is DSR, record that fact in the
// scheduler so that we don't try to write a non DSR stream again.
// Note that this means that in the presence of many large control
// streams and DSR streams, we won't completely prioritize control
// streams but they will not be starved.
if (nextStream && !nextStream->hasSchedulableData()) {
nextStreamDsr_ = true;
}
return {};
}
bool StreamFrameScheduler::hasPendingData() const {
return !nextStreamDsr_ &&
(conn_.streamManager->hasNonDSRLoss() ||
(conn_.streamManager->hasNonDSRWritable() &&
getSendConnFlowControlBytesWire(conn_) > 0));
return conn_.streamManager->hasLoss() ||
(conn_.streamManager->hasWritable() &&
getSendConnFlowControlBytesWire(conn_) > 0);
}
quic::Expected<bool, QuicError> StreamFrameScheduler::writeStreamFrame(
@@ -695,9 +670,8 @@ quic::Expected<bool, QuicError> StreamFrameScheduler::writeStreamFrame(
uint64_t flowControlLen =
std::min(getSendStreamFlowControlBytesWire(stream), connWritableBytes);
uint64_t bufferLen = stream.pendingWrites.chainLength();
// We should never write a FIN from the non-DSR scheduler for a DSR stream.
bool canWriteFin = stream.finalWriteOffset.has_value() &&
bufferLen <= flowControlLen && stream.writeBufMeta.offset == 0;
bool canWriteFin =
stream.finalWriteOffset.has_value() && bufferLen <= flowControlLen;
auto writeOffset = stream.currentWriteOffset;
auto res = writeStreamFrameHeader(
builder,
@@ -741,8 +715,7 @@ quic::Expected<bool, QuicError> RstStreamScheduler::writeRsts(
conn_.streamManager->getStream(streamId).value_or(nullptr);
CHECK(streamState) << "Stream " << streamId
<< " not found when going through resets";
if (streamState->pendingWrites.empty() &&
streamState->writeBufMeta.length == 0) {
if (streamState->pendingWrites.empty()) {
// We only write a RESET_STREAM or RESET_STREAM_AT frame for a stream
// once we've written out all data that needs to be delivered reliably.
// While this is not something that's mandated by the spec, we're doing
@@ -1029,8 +1002,7 @@ CloningScheduler::CloningScheduler(
cipherOverhead_(cipherOverhead) {}
bool CloningScheduler::hasData() const {
return frameScheduler_.hasData() ||
conn_.outstandings.numOutstanding() > conn_.outstandings.dsrCount;
return frameScheduler_.hasData() || conn_.outstandings.numOutstanding() > 0;
}
quic::Expected<SchedulingResult, QuicError>
@@ -1053,7 +1025,7 @@ CloningScheduler::scheduleFramesForPacket(
std::move(builder).releaseOutputBuffer();
// Look for an outstanding packet that's no larger than the writableBytes
for (auto& outstandingPacket : conn_.outstandings.packets) {
if (outstandingPacket.declaredLost || outstandingPacket.isDSRPacket) {
if (outstandingPacket.declaredLost) {
continue;
}
auto opPnSpace = outstandingPacket.packet.header.getPacketNumberSpace();