void HQSession::onFlowControlUpdate()

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();
  }
}