in proxygen/lib/http/session/HQSession.cpp [1745:1797]
void HQSession::onFlowControlUpdate(quic::StreamId id) noexcept {
VLOG(4) << __func__ << " sess=" << *this << ": streamID=" << id;
auto flowControl = sock_->getStreamFlowControl(id);
if (flowControl.hasError()) {
LOG(ERROR) << "Got error=" << flowControl.error() << " streamID=" << id;
return;
}
auto ctrlStream = findControlStream(id);
if (ctrlStream && flowControl->sendWindowAvailable > 0) {
if (sock_ && sock_->getState() && sock_->getState()->qLogger) {
sock_->getState()->qLogger->addStreamStateUpdate(
id,
quic::getFlowControlWindowAvailable(flowControl->sendWindowAvailable),
std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - ctrlStream->createdTime));
}
scheduleWrite();
return;
}
auto stream = findEgressStream(id);
if (!stream) {
LOG(ERROR) << "Got flow control update for unknown streamID=" << id
<< " sess=" << this;
return;
}
auto& txn = stream->txn_;
// Check if this stream has flow control, or has only EOM pending
if (flowControl->sendWindowAvailable > 0 ||
(!stream->hasPendingBody() && stream->hasPendingEOM())) {
// TODO: are we intentionally piggyback the time value for flow control
// window here?
if (sock_ && sock_->getState() && sock_->getState()->qLogger) {
sock_->getState()->qLogger->addStreamStateUpdate(
id,
quic::getFlowControlWindowAvailable(flowControl->sendWindowAvailable),
std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - stream->createdTime));
}
if (stream->hasPendingEgress()) {
txnEgressQueue_.signalPendingEgress(stream->queueHandle_.getHandle());
}
if (!stream->detached_ && txn.isEgressPaused()) {
// txn might be paused
txn.resumeEgress();
}
scheduleWrite();
}
}