proxygen
proxygen::FlowControlFilter Class Reference

#include <FlowControlFilter.h>

Inheritance diagram for proxygen::FlowControlFilter:
proxygen::PassThroughHTTPCodecFilter proxygen::GenericFilter< T1, T2, set_callback, TakeOwnership, Dp > T1 T2

Classes

class  Callback
 

Public Member Functions

 FlowControlFilter (Callback &callback, folly::IOBufQueue &writeBuf, HTTPCodec *codec, uint32_t recvCapacity=0)
 
void setReceiveWindowSize (folly::IOBufQueue &writeBuf, uint32_t capacity)
 
bool ingressBytesProcessed (folly::IOBufQueue &writeBuf, uint32_t delta)
 
uint32_t getAvailableSend () const
 
bool isReusable () const override
 
void onBody (StreamID stream, std::unique_ptr< folly::IOBuf > chain, uint16_t padding) override
 
void onWindowUpdate (StreamID stream, uint32_t amount) override
 
size_t generateBody (folly::IOBufQueue &writeBuf, StreamID stream, std::unique_ptr< folly::IOBuf > chain, folly::Optional< uint8_t > padding, bool eom) override
 
size_t generateWindowUpdate (folly::IOBufQueue &writeBuf, StreamID stream, uint32_t delta) override
 
- Public Member Functions inherited from proxygen::PassThroughHTTPCodecFilter
 PassThroughHTTPCodecFilter (bool calls=true, bool callbacks=true)
 
void onMessageBegin (StreamID stream, HTTPMessage *msg) override
 
void onPushMessageBegin (StreamID stream, StreamID assocStream, HTTPMessage *msg) override
 
void onExMessageBegin (StreamID stream, StreamID controlStream, bool unidirectional, HTTPMessage *msg) override
 
void onHeadersComplete (StreamID stream, std::unique_ptr< HTTPMessage > msg) override
 
void onBody (StreamID stream, std::unique_ptr< folly::IOBuf > chain, uint16_t padding) override
 
void onChunkHeader (StreamID stream, size_t length) override
 
void onChunkComplete (StreamID stream) override
 
void onTrailersComplete (StreamID stream, std::unique_ptr< HTTPHeaders > trailers) override
 
void onMessageComplete (StreamID stream, bool upgrade) override
 
void onFrameHeader (StreamID stream_id, uint8_t flags, uint64_t length, uint8_t type, uint16_t version=0) override
 
void onError (StreamID stream, const HTTPException &error, bool newStream=false) override
 
void onAbort (StreamID stream, ErrorCode code) override
 
void onGoaway (uint64_t lastGoodStreamID, ErrorCode code, std::unique_ptr< folly::IOBuf > debugData=nullptr) override
 
void onPingRequest (uint64_t uniqueID) override
 
void onPingReply (uint64_t uniqueID) override
 
void onWindowUpdate (StreamID stream, uint32_t amount) override
 
void onSettings (const SettingsList &settings) override
 
void onSettingsAck () override
 
void onPriority (StreamID stream, const HTTPMessage::HTTPPriority &pri) override
 
bool onNativeProtocolUpgrade (StreamID stream, CodecProtocol protocol, const std::string &protocolString, HTTPMessage &msg) override
 
void onGenerateFrameHeader (StreamID streamID, uint8_t type, uint64_t length, uint16_t version) override
 
void onCertificateRequest (uint16_t requestId, std::unique_ptr< folly::IOBuf > authRequest) override
 
void onCertificate (uint16_t certId, std::unique_ptr< folly::IOBuf > authenticator) override
 
uint32_t numOutgoingStreams () const override
 
uint32_t numIncomingStreams () const override
 
HPACKTableInfo getHPACKTableInfo () const override
 
CodecProtocol getProtocol () const override
 
const std::stringgetUserAgent () const override
 
TransportDirection getTransportDirection () const override
 
bool supportsStreamFlowControl () const override
 
bool supportsSessionFlowControl () const override
 
StreamID createStream () override
 
void setCallback (HTTPCodec::Callback *callback) override
 
bool isBusy () const override
 
void setParserPaused (bool paused) override
 
size_t onIngress (const folly::IOBuf &buf) override
 
void onIngressEOF () override
 
bool onIngressUpgradeMessage (const HTTPMessage &msg) override
 
bool isReusable () const override
 
bool isWaitingToDrain () const override
 
bool closeOnEgressComplete () const override
 
bool supportsParallelRequests () const override
 
bool supportsPushTransactions () const override
 
size_t generateConnectionPreface (folly::IOBufQueue &writeBuf) override
 
void generateHeader (folly::IOBufQueue &writeBuf, StreamID stream, const HTTPMessage &msg, bool eom, HTTPHeaderSize *size) override
 
void generatePushPromise (folly::IOBufQueue &writeBuf, StreamID stream, const HTTPMessage &msg, StreamID assocStream, bool eom, HTTPHeaderSize *size) override
 
void generateExHeader (folly::IOBufQueue &writeBuf, StreamID stream, const HTTPMessage &msg, const HTTPCodec::ExAttributes &exAttributes, bool eom, HTTPHeaderSize *size) override
 
size_t generateBody (folly::IOBufQueue &writeBuf, StreamID stream, std::unique_ptr< folly::IOBuf > chain, folly::Optional< uint8_t > padding, bool eom) override
 
size_t generateChunkHeader (folly::IOBufQueue &writeBuf, StreamID stream, size_t length) override
 
size_t generateChunkTerminator (folly::IOBufQueue &writeBuf, StreamID stream) override
 
size_t generateTrailers (folly::IOBufQueue &writeBuf, StreamID stream, const HTTPHeaders &trailers) override
 
size_t generateEOM (folly::IOBufQueue &writeBuf, StreamID stream) override
 
size_t generateRstStream (folly::IOBufQueue &writeBuf, StreamID stream, ErrorCode statusCode) override
 
size_t generateGoaway (folly::IOBufQueue &writeBuf, StreamID lastStream, ErrorCode statusCode, std::unique_ptr< folly::IOBuf > debugData=nullptr) override
 
size_t generatePingRequest (folly::IOBufQueue &writeBuf) override
 
size_t generatePingReply (folly::IOBufQueue &writeBuf, uint64_t uniqueID) override
 
size_t generateSettings (folly::IOBufQueue &writeBuf) override
 
size_t generateSettingsAck (folly::IOBufQueue &writeBuf) override
 
size_t generateWindowUpdate (folly::IOBufQueue &writeBuf, StreamID stream, uint32_t delta) override
 
size_t generatePriority (folly::IOBufQueue &writeBuf, StreamID stream, const HTTPMessage::HTTPPriority &pri) override
 
size_t generateCertificateRequest (folly::IOBufQueue &writeBuf, uint16_t requestId, std::unique_ptr< folly::IOBuf > chain) override
 
size_t generateCertificate (folly::IOBufQueue &writeBuf, uint16_t certId, std::unique_ptr< folly::IOBuf > certData) override
 
HTTPSettingsgetEgressSettings () override
 
const HTTPSettingsgetIngressSettings () const override
 
void setHeaderCodecStats (HeaderCodec::Stats *stats) override
 
void enableDoubleGoawayDrain () override
 
HTTPCodec::StreamID getLastIncomingStreamID () const override
 
uint32_t getDefaultWindowSize () const override
 
size_t addPriorityNodes (PriorityQueue &queue, folly::IOBufQueue &writeBuf, uint8_t maxLevel) override
 
StreamID mapPriorityToDependency (uint8_t priority) const override
 
int8_t mapDependencyToPriority (StreamID parent) const override
 
- Public Member Functions inherited from proxygen::GenericFilter< T1, T2, set_callback, TakeOwnership, Dp >
 GenericFilter (bool calls, bool callbacks)
 
 ~GenericFilter () override
 
void append (Filter *nextFilter)
 

Private Attributes

Callbacknotify_
 
Window recvWindow_
 
Window sendWindow_
 
int32_t toAck_ {0}
 
bool error_:1
 
bool sendsBlocked_:1
 

Additional Inherited Members

- Public Types inherited from proxygen::GenericFilter< T1, T2, set_callback, TakeOwnership, Dp >
using Filter = GenericFilter< T1, T2, set_callback, TakeOwnership, Dp >
 
- Public Attributes inherited from proxygen::GenericFilter< T1, T2, set_callback, TakeOwnership, Dp >
const bool kWantsCalls_
 
const bool kWantsCallbacks_
 
- Protected Member Functions inherited from proxygen::GenericFilter< T1, T2, set_callback, TakeOwnership, Dp >
void setCallbackInternal (T2 *cb)
 
void drop ()
 
- Protected Attributes inherited from proxygen::GenericFilter< T1, T2, set_callback, TakeOwnership, Dp >
T1call_ {nullptr}
 
T2callback_ {nullptr}
 

Detailed Description

This class implements the logic for managing per-session flow control. Not every codec is interested in per-session flow control, so this filter can only be added in that case or else it is an error.

Definition at line 26 of file FlowControlFilter.h.

Constructor & Destructor Documentation

proxygen::FlowControlFilter::FlowControlFilter ( Callback callback,
folly::IOBufQueue writeBuf,
HTTPCodec codec,
uint32_t  recvCapacity = 0 
)
explicit

Construct a flow control filter.

Parameters
callbackA channel to be notified when the window is not full anymore.
writeBufThe buffer to write egress on. This constructor may generate a window update frame on this buffer.
codecThe codec implementation.
recvCapacityThe initial size of the conn-level recv window. It must be >= codec->getDefaultWindowSize(), or it will generate an immediate window update into writeBuf. 0 means use the codec default.

Definition at line 23 of file FlowControlFilter.cpp.

References proxygen::HTTPCodec::generateWindowUpdate(), proxygen::PassThroughHTTPCodecFilter::getDefaultWindowSize(), proxygen::HTTPCodec::getDefaultWindowSize(), recvWindow_, and proxygen::Window::setCapacity().

26  :
27  notify_(callback),
28  recvWindow_(codec->getDefaultWindowSize()),
29  sendWindow_(codec->getDefaultWindowSize()),
30  error_(false),
31  sendsBlocked_(false) {
32  if (recvCapacity > 0) {
33  if (recvCapacity < codec->getDefaultWindowSize()) {
34  VLOG(4) << "Ignoring low conn-level recv window size of " << recvCapacity;
35  } else if (recvCapacity > codec->getDefaultWindowSize()) {
36  auto delta = recvCapacity - codec->getDefaultWindowSize();
37  VLOG(4) << "Incrementing default conn-level recv window by " << delta;
38  CHECK(recvWindow_.setCapacity(recvCapacity));
39  codec->generateWindowUpdate(writeBuf, 0, delta);
40  }
41  }
42 }
CodecFactory codec
uint32_t getDefaultWindowSize() const override
bool setCapacity(uint32_t capacity)
Definition: Window.cpp:84

Member Function Documentation

size_t proxygen::FlowControlFilter::generateBody ( folly::IOBufQueue writeBuf,
StreamID  stream,
std::unique_ptr< folly::IOBuf chain,
folly::Optional< uint8_t padding,
bool  eom 
)
override

Definition at line 145 of file FlowControlFilter.cpp.

References proxygen::GenericFilter< T1, T2, set_callback, TakeOwnership, Dp >::call_, folly::IOBuf::computeChainDataLength(), proxygen::Window::getNonNegativeSize(), proxygen::Window::getSize(), folly::gen::move, notify_, proxygen::FlowControlFilter::Callback::onConnectionSendWindowClosed(), proxygen::Window::reserve(), sendsBlocked_, sendWindow_, and uint8_t.

149  {
150  uint8_t padLen = padding ? *padding : 0;
151  bool success = sendWindow_.reserve(
152  chain->computeChainDataLength() + padLen);
153  VLOG(5) << "Sending " << chain->computeChainDataLength()
154  << " bytes, sendWindow=" << sendWindow_.getSize();
155 
156  // In the future, maybe make this DCHECK
157  CHECK(success) << "Session-level send window underflowed! "
158  << "Too much data sent without WINDOW_UPDATES!";
159 
160  if (sendWindow_.getNonNegativeSize() == 0) {
161  // Need to inform when the send window is no longer full
162  VLOG(4) << "Send window closed";
163  sendsBlocked_ = true;
165  }
166 
167  return call_->generateBody(writeBuf, stream, std::move(chain), padding,
168  eom);
169 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
int32_t getSize() const
Definition: Window.cpp:23
bool reserve(uint32_t amount, bool strict=true)
Definition: Window.cpp:41
virtual void onConnectionSendWindowClosed()=0
std::size_t computeChainDataLength() const
Definition: IOBuf.cpp:501
uint32_t getNonNegativeSize() const
Definition: Window.cpp:27
size_t proxygen::FlowControlFilter::generateWindowUpdate ( folly::IOBufQueue writeBuf,
StreamID  stream,
uint32_t  delta 
)
override

Definition at line 171 of file FlowControlFilter.cpp.

References proxygen::GenericFilter< T1, T2, set_callback, TakeOwnership, Dp >::call_.

173  {
174  CHECK(stream) << " someone tried to manually manipulate a conn-level window";
175  return call_->generateWindowUpdate(writeBuf, stream, delta);
176 }
uint32_t proxygen::FlowControlFilter::getAvailableSend ( ) const
Returns
the number of bytes available in the connection-level send window

Definition at line 85 of file FlowControlFilter.cpp.

References proxygen::Window::getNonNegativeSize(), and sendWindow_.

Referenced by proxygen::HTTPSession::getNextToSend(), proxygen::HTTPSession::isConnWindowFull(), and proxygen::HTTPSession::runLoopCallback().

85  {
87 }
uint32_t getNonNegativeSize() const
Definition: Window.cpp:27
bool proxygen::FlowControlFilter::ingressBytesProcessed ( folly::IOBufQueue writeBuf,
uint32_t  delta 
)

Notify the flow control filter that some ingress bytes were processed. If the number of bytes to acknowledge exceeds half the receive window's capacity, a WINDOW_UPDATE frame will be written.

Parameters
writeBufThe buffer to write egress on. This function may generate a WINDOW_UPDATE on this buffer.
deltaThe number of bytes that were processed.
Returns
true iff we wrote a WINDOW_UPDATE frame to the write buf.

Definition at line 69 of file FlowControlFilter.cpp.

References proxygen::GenericFilter< T1, T2, set_callback, TakeOwnership, Dp >::call_, proxygen::Window::free(), proxygen::Window::getCapacity(), recvWindow_, toAck_, and uint32_t.

Referenced by proxygen::HTTPSession::notifyIngressBodyProcessed(), and proxygen::HTTPSession::onBody().

70  {
71  toAck_ += delta;
72  bool willAck = (toAck_ > 0 &&
74  VLOG(4) << "processed " << delta << " toAck_=" << toAck_
75  << " bytes, will ack=" << willAck;
76  if (willAck) {
77  CHECK(recvWindow_.free(toAck_));
78  call_->generateWindowUpdate(writeBuf, 0, toAck_);
79  toAck_ = 0;
80  return true;
81  }
82  return false;
83 }
uint32_t getCapacity() const
Definition: Window.cpp:32
bool free(uint32_t amount)
Definition: Window.cpp:63
bool proxygen::FlowControlFilter::isReusable ( ) const
override

Definition at line 89 of file FlowControlFilter.cpp.

References proxygen::GenericFilter< T1, T2, set_callback, TakeOwnership, Dp >::call_, and error_.

89  {
90  if (error_) {
91  return false;
92  }
93  return call_->isReusable();
94 }
void proxygen::FlowControlFilter::onBody ( StreamID  stream,
std::unique_ptr< folly::IOBuf chain,
uint16_t  padding 
)
override

Definition at line 96 of file FlowControlFilter.cpp.

References proxygen::GenericFilter< T1, T2, set_callback, TakeOwnership, Dp >::callback_, folly::IOBuf::computeChainDataLength(), error_, proxygen::Window::free(), proxygen::Window::getSize(), folly::gen::move, recvWindow_, proxygen::Window::reserve(), toAck_, and uint64_t.

98  {
99  uint64_t amount = chain->computeChainDataLength();
100  if (!recvWindow_.reserve(amount + padding)) {
101  error_ = true;
102  HTTPException ex = getException(
103  folly::to<std::string>(
104  "Failed to reserve receive window, window size=",
105  recvWindow_.getSize(), ", amount=", amount));
106  callback_->onError(0, ex, false);
107  } else {
108  if (VLOG_IS_ON(4) && recvWindow_.getSize() == 0) {
109  VLOG(4) << "recvWindow full";
110  }
111  toAck_ += padding;
112  CHECK(recvWindow_.free(padding));
113  callback_->onBody(stream, std::move(chain), padding);
114  }
115 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
int32_t getSize() const
Definition: Window.cpp:23
bool reserve(uint32_t amount, bool strict=true)
Definition: Window.cpp:41
std::size_t computeChainDataLength() const
Definition: IOBuf.cpp:501
bool free(uint32_t amount)
Definition: Window.cpp:63
void proxygen::FlowControlFilter::onWindowUpdate ( StreamID  stream,
uint32_t  amount 
)
override

Definition at line 117 of file FlowControlFilter.cpp.

References proxygen::GenericFilter< T1, T2, set_callback, TakeOwnership, Dp >::callback_, error_, proxygen::Window::free(), proxygen::Window::getNonNegativeSize(), proxygen::Window::getOutstanding(), proxygen::Window::getSize(), notify_, proxygen::FlowControlFilter::Callback::onConnectionSendWindowOpen(), sendsBlocked_, and sendWindow_.

117  {
118  if (!stream) {
119  bool success = sendWindow_.free(amount);
120  VLOG(4) << "Remote side ack'd " << amount << " bytes, sendWindow=" <<
122  if (!success) {
123  LOG(WARNING) << "Remote side sent connection-level WINDOW_UPDATE "
124  << "that could not be applied. Aborting session.";
125  // If something went wrong applying the flow control change, abort
126  // the entire session.
127  error_ = true;
128  HTTPException ex = getException(
129  folly::to<std::string>(
130  "Failed to update send window, outstanding=",
131  sendWindow_.getOutstanding(), ", amount=", amount));
132  callback_->onError(stream, ex, false);
133  }
135  VLOG(4) << "Send window opened";
136  sendsBlocked_ = false;
138  }
139  // Don't forward.
140  } else {
141  callback_->onWindowUpdate(stream, amount);
142  }
143 }
uint32_t getOutstanding() const
Definition: Window.cpp:37
int32_t getSize() const
Definition: Window.cpp:23
bool free(uint32_t amount)
Definition: Window.cpp:63
uint32_t getNonNegativeSize() const
Definition: Window.cpp:27
void proxygen::FlowControlFilter::setReceiveWindowSize ( folly::IOBufQueue writeBuf,
uint32_t  capacity 
)

Modify the session receive window

Parameters
writeBufThe buffer to write egress on. This constructor may generate a window update frame on this buffer.
capacityThe initial size of the conn-level recv window. It must be >= the codec default.

Definition at line 44 of file FlowControlFilter.cpp.

References proxygen::GenericFilter< T1, T2, set_callback, TakeOwnership, Dp >::call_, proxygen::Window::getCapacity(), int32_t, recvWindow_, proxygen::Window::setCapacity(), and toAck_.

Referenced by proxygen::HTTPSession::onNativeProtocolUpgradeImpl(), and proxygen::HTTPSession::startNow().

45  {
46  if (capacity < recvWindow_.getCapacity()) {
47  VLOG(4) << "Ignoring low conn-level recv window size of " << capacity;
48  return;
49  }
50  int32_t delta = capacity - recvWindow_.getCapacity();
51  if (delta < 0) {
52  // For now, we're disallowing shrinking the window, since it can lead
53  // to FLOW_CONTROL_ERRORs if there is data in flight.
54  VLOG(4) << "Refusing to shrink the recv window";
55  return;
56  }
57  VLOG(4) << "Incrementing default conn-level recv window by " << delta;
58  if (!recvWindow_.setCapacity(capacity)) {
59  VLOG(2) << "Failed setting conn-level recv window capacity to " << capacity;
60  return;
61  }
62  toAck_ += delta;
63  if (toAck_ > 0) {
64  call_->generateWindowUpdate(writeBuf, 0, delta);
65  toAck_ = 0;
66  }
67 }
uint32_t getCapacity() const
Definition: Window.cpp:32
bool setCapacity(uint32_t capacity)
Definition: Window.cpp:84

Member Data Documentation

bool proxygen::FlowControlFilter::error_
private

Definition at line 108 of file FlowControlFilter.h.

Referenced by isReusable(), onBody(), and onWindowUpdate().

Callback& proxygen::FlowControlFilter::notify_
private

Definition at line 104 of file FlowControlFilter.h.

Referenced by generateBody(), and onWindowUpdate().

Window proxygen::FlowControlFilter::recvWindow_
private
bool proxygen::FlowControlFilter::sendsBlocked_
private

Definition at line 109 of file FlowControlFilter.h.

Referenced by generateBody(), and onWindowUpdate().

Window proxygen::FlowControlFilter::sendWindow_
private

Definition at line 106 of file FlowControlFilter.h.

Referenced by generateBody(), getAvailableSend(), and onWindowUpdate().

int32_t proxygen::FlowControlFilter::toAck_ {0}
private

Definition at line 107 of file FlowControlFilter.h.

Referenced by ingressBytesProcessed(), onBody(), and setReceiveWindowSize().


The documentation for this class was generated from the following files: