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