1
0
mirror of https://github.com/facebookincubator/mvfst.git synced 2025-11-09 10:00:57 +03:00
Files
mvfst/quic/api/test/TestQuicTransport.h
Brandon Schlinker 20c17a882b PacketsWrittenEvent observer event
Summary:
Currently the `packetsWritten` observer event is only triggered when ACK-eliciting packets are written to the network. This change makes it so that the event is triggered even when non ACK-eliciting packets are written. In addition, this change increases the information provided in the observer event to reduce the processing that must be performed by observers.

More specifically, this diff makes the following changes:
- It creates two new structs — `WriteEvent` and `PacketsWrittenEvent` — and makes `PacketsWrittenEvent` and `AppLimitedEvent` inherit from `WriteEvent`, which contains the base set of fields that appear in both derived events. The base set of fields includes `writeCount` and the reference to the list of `OutstandingPackets`.
- A `PacketsWrittenEvent` is generated after each write loop during which packets are written.
  - The `PacketsWrittenEvent` records the total number of packets written (the sum of ACK-eliciting and non ACK-eliciting packets written) and the total number of ACK-eliciting packets written during the last loop. By exposing this information, observers can determine whether there is value in inspecting the list of `OutstandingPackets` before doing so.
  - In the future, I'll extend this event to also report the number of stream bytes written.
- It adopts a new builder pattern for observer events to make it easier to create instances of these structures:
  - We use this approach instead of aggregate initialization (specifically designated initializers via aggregate initialization), because designated initializers (C++20 feature, although supported by some compilers long before) is not yet supported on all platforms for which we need this code to compile.
  - I intend to change the other observer events to use this pattern as the number of arguments in some of their constructors makes them increasingly difficult to deal with.

Reviewed By: mjoras

Differential Revision: D31216724

fbshipit-source-id: 42ceb922d46ab0e0dc356f8726c2d0467a219587
2021-12-03 11:17:14 -08:00

159 lines
3.8 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
#pragma once
#include <quic/api/QuicTransportBase.h>
#include <quic/api/QuicTransportFunctions.h>
#include <quic/common/test/TestUtils.h>
#include <quic/fizz/server/handshake/FizzServerQuicHandshakeContext.h>
namespace quic {
class TestQuicTransport
: public QuicTransportBase,
public std::enable_shared_from_this<TestQuicTransport> {
public:
TestQuicTransport(
folly::EventBase* evb,
std::unique_ptr<folly::AsyncUDPSocket> socket,
ConnectionCallback& cb)
: QuicTransportBase(evb, std::move(socket)) {
setConnectionCallback(&cb);
conn_.reset(new QuicServerConnectionState(
FizzServerQuicHandshakeContext::Builder().build()));
conn_->clientConnectionId = ConnectionId({9, 8, 7, 6});
conn_->serverConnectionId = ConnectionId({1, 2, 3, 4});
conn_->version = QuicVersion::MVFST;
aead = test::createNoOpAead();
headerCipher = test::createNoOpHeaderCipher();
}
~TestQuicTransport() override {
// we need to call close in the derived class.
resetConnectionCallbacks();
closeImpl(
std::make_pair(
QuicErrorCode(LocalErrorCode::SHUTTING_DOWN),
std::string("shutdown")),
false);
}
QuicVersion getVersion() {
auto& conn = getConnectionState();
return conn.version.value_or(*conn.originalVersion);
}
void updateWriteLooper(bool thisIteration) {
QuicTransportBase::updateWriteLooper(thisIteration);
}
void pacedWrite(bool fromTimer) {
pacedWriteDataToSocket(fromTimer);
}
bool isPacingScheduled() {
return writeLooper_->isScheduled();
}
void onReadData(
const folly::SocketAddress& /*peer*/,
NetworkDataSingle&& /*networkData*/) noexcept override {}
void writeData() override {
if (closed) {
return;
}
writeQuicDataToSocket(
*socket_,
*conn_,
*conn_->clientConnectionId,
*conn_->serverConnectionId,
*aead,
*headerCipher,
getVersion(),
(isConnectionPaced(*conn_)
? conn_->pacer->updateAndGetWriteBatchSize(Clock::now())
: conn_->transportSettings.writeConnectionDataPacketsLimit));
}
void closeTransport() override {
closed = true;
}
bool hasWriteCipher() const override {
return true;
}
std::shared_ptr<QuicTransportBase> sharedGuard() override {
return shared_from_this();
}
void unbindConnection() override {}
QuicServerConnectionState& getConnectionState() {
return *dynamic_cast<QuicServerConnectionState*>(conn_.get());
}
auto getAckTimeout() {
return &ackTimeout_;
}
auto& getPathValidationTimeout() {
return pathValidationTimeout_;
}
auto& lossTimeout() {
return lossTimeout_;
}
auto& idleTimeout() {
return idleTimeout_;
}
CloseState closeState() {
return closeState_;
}
folly::HHWheelTimer* getTimer() {
return &getEventBase()->timer();
}
void drainImmediately() {
drainTimeoutExpired();
}
void setIdleTimerNow() {
setIdleTimer();
}
void invokeNotifyStartWritingFromAppRateLimited() {
notifyStartWritingFromAppRateLimited();
}
void invokeNotifyPacketsWritten(
const uint64_t numPacketsWritten,
const uint64_t numAckElicitingPacketsWritten) {
notifyPacketsWritten(numPacketsWritten, numAckElicitingPacketsWritten);
}
void invokeNotifyAppRateLimited() {
notifyAppRateLimited();
}
void setTransportReadyNotified(bool transportReadyNotified) {
transportReadyNotified_ = transportReadyNotified;
}
std::unique_ptr<Aead> aead;
std::unique_ptr<PacketNumberCipher> headerCipher;
bool closed{false};
};
} // namespace quic