bool RLCongestionController::setNetworkState()

in congestion_control/RLCongestionController.cpp [122:189]


bool RLCongestionController::setNetworkState(
    const folly::Optional<AckEvent> &ack,
    const folly::Optional<LossEvent> &loss, NetworkState &obs) {
  const auto &state = conn_.lossState;

  const auto &rttMin = minRTTFilter_.GetBest();
  const auto &rttStanding = standingRTTFilter_.GetBest().count();
  const auto &delay =
      duration_cast<microseconds>(conn_.lossState.lrtt - rttMin).count();
  if (rttStanding == 0 || delay < 0) {
    LOG(ERROR)
        << "Invalid rttStanding or delay, skipping network state update: "
        << "rttStanding = " << rttStanding << ", delay = " << delay << " "
        << conn_;
    return false;
  }

  const float normMs = env_->normMs();
  const float normBytes = env_->normBytes();

  obs[Field::RTT_MIN] = rttMin.count() / 1000.0 / normMs;
  obs[Field::RTT_STANDING] = rttStanding / 1000.0 / normMs;
  obs[Field::LRTT] = state.lrtt.count() / 1000.0 / normMs;
  obs[Field::SRTT] = state.srtt.count() / 1000.0 / normMs;
  obs[Field::RTT_VAR] = state.rttvar.count() / 1000.0 / normMs;
  obs[Field::DELAY] = delay / 1000.0 / normMs;

  obs[Field::CWND] = cwndBytes_ / normBytes;
  obs[Field::IN_FLIGHT] = bytesInFlight_ / normBytes;
  obs[Field::WRITABLE] = getWritableBytes() / normBytes;
  obs[Field::SENT] = (state.totalBytesSent - prevTotalBytesSent_) / normBytes;
  obs[Field::RECEIVED] =
      (state.totalBytesRecvd - prevTotalBytesRecvd_) / normBytes;
  obs[Field::RETRANSMITTED] =
      (state.totalBytesRetransmitted - prevTotalBytesRetransmitted_) /
      normBytes;

  // The throughput is in bytes / s => we normalize it with `normBytes`.
  DCHECK(bandwidthSampler_.getBandwidth().unitType ==
         Bandwidth::UnitType::BYTES);
  obs[Field::THROUGHPUT] =
      bandwidthSampler_.getBandwidth().normalize() / normBytes;

  obs[Field::PTO_COUNT] = state.ptoCount;
  obs[Field::TOTAL_PTO_DELTA] = state.totalPTOCount - prevTotalPTOCount_;
  obs[Field::RTX_COUNT] = state.rtxCount - prevRtxCount_;
  obs[Field::TIMEOUT_BASED_RTX_COUNT] =
      state.timeoutBasedRtxCount - prevTimeoutBasedRtxCount_;

  if (ack && ack->largestAckedPacket.hasValue()) {
    obs[Field::ACKED] = ack->ackedBytes / normBytes;
  }

  if (loss) {
    obs[Field::LOST] = loss->lostBytes / normBytes;
    obs[Field::PERSISTENT_CONGESTION] = loss->persistentCongestion;
  }

  // Update prev state values
  prevTotalBytesSent_ = state.totalBytesSent;
  prevTotalBytesRecvd_ = state.totalBytesRecvd;
  prevTotalBytesRetransmitted_ = state.totalBytesRetransmitted;
  prevTotalPTOCount_ = state.totalPTOCount;
  prevRtxCount_ = state.rtxCount;
  prevTimeoutBasedRtxCount_ = state.timeoutBasedRtxCount;

  return true;
}