void ProxyDestination::handleRxmittingConnection()

in mcrouter/ProxyDestination-inl.h [64:124]


void ProxyDestination<Transport>::handleRxmittingConnection(
    const carbon::Result result,
    uint64_t latency) {
  constexpr uint32_t kReconnectionHoldoffFactor = 25;
  if (!transport_) {
    return;
  }
  const auto retransCycles =
      proxy().router().opts().collect_rxmit_stats_every_hz;
  if (retransCycles > 0 &&
      (isDataTimeoutResult(result) || latencyAboveThreshold(latency))) {
    const auto curCycles = cycles::getCpuCycles();
    if (curCycles > lastRetransCycles_ + retransCycles) {
      lastRetransCycles_ = curCycles;
      const auto currRetransPerKByte = transport_->getRetransmitsPerKb();
      if (currRetransPerKByte >= 0.0) {
        stats().retransPerKByte = currRetransPerKByte;
        proxy().stats().setValue(
            retrans_per_kbyte_max_stat,
            std::max(
                proxy().stats().getValue(retrans_per_kbyte_max_stat),
                static_cast<uint64_t>(currRetransPerKByte)));
        proxy().stats().increment(
            retrans_per_kbyte_sum_stat,
            static_cast<int64_t>(currRetransPerKByte));
        proxy().stats().increment(retrans_num_total_stat);
      }

      if (proxy().router().isRxmitReconnectionDisabled()) {
        return;
      }

      if (rxmitsToCloseConnection_ > 0 &&
          currRetransPerKByte >= rxmitsToCloseConnection_) {
        std::uniform_int_distribution<uint64_t> dist(
            1, kReconnectionHoldoffFactor);
        const uint64_t reconnectionJitters =
            retransCycles * dist(proxy().randomGenerator());
        if (lastConnCloseCycles_ + reconnectionJitters > curCycles) {
          return;
        }
        transport_->closeNow();
        proxy().stats().increment(retrans_closed_connections_stat);
        lastConnCloseCycles_ = curCycles;

        const auto maxThreshold =
            proxy().router().opts().max_rxmit_reconnect_threshold;
        const uint64_t maxRxmitReconnThreshold = maxThreshold == 0
            ? std::numeric_limits<uint64_t>::max()
            : maxThreshold;
        rxmitsToCloseConnection_ =
            std::min(maxRxmitReconnThreshold, 2 * rxmitsToCloseConnection_);
      } else if (3 * currRetransPerKByte < rxmitsToCloseConnection_) {
        const auto minThreshold =
            proxy().router().opts().min_rxmit_reconnect_threshold;
        rxmitsToCloseConnection_ =
            std::max(minThreshold, rxmitsToCloseConnection_ / 2);
      }
    }
  }
}