in mcrouter/routes/OutstandingLimitRoute.h [68:143]
ReplyT<Request> route(const Request& req) {
if (outstanding_ == maxOutstanding_) {
auto& ctx = fiber_local<RouterInfo>::getSharedCtx();
auto senderId = ctx->senderId();
auto& entry = [&]() -> QueueEntry& {
auto entry_it = senderIdToEntry_.find(senderId);
if (entry_it != senderIdToEntry_.end()) {
return *entry_it->second;
}
blockedRequests_.push_back(std::make_unique<QueueEntry>(senderId));
if (senderId) {
senderIdToEntry_[senderId] = blockedRequests_.back().get();
}
return *blockedRequests_.back();
}();
auto& stats = ctx->proxy().stats();
folly::fibers::Baton baton;
int64_t waitingSince = 0;
if (carbon::GetLike<Request>::value) {
++currentGetReqsWaiting_;
waitingSince = nowUs();
} else if (carbon::UpdateLike<Request>::value) {
++currentUpdateReqsWaiting_;
waitingSince = nowUs();
}
entry.batons.push_back(&baton);
baton.wait();
if (waitingSince > 0) {
if (carbon::GetLike<Request>::value) {
stats.increment(
outstanding_route_get_wait_time_sum_us_stat,
static_cast<uint64_t>(nowUs() - waitingSince));
stats.increment(
outstanding_route_get_reqs_queued_helper_stat,
currentGetReqsWaiting_);
--currentGetReqsWaiting_;
stats.increment(outstanding_route_get_reqs_queued_stat, 1);
} else if (carbon::UpdateLike<Request>::value) {
stats.increment(
outstanding_route_update_wait_time_sum_us_stat,
static_cast<uint64_t>(nowUs() - waitingSince));
stats.increment(
outstanding_route_update_reqs_queued_helper_stat,
currentUpdateReqsWaiting_);
--currentUpdateReqsWaiting_;
stats.increment(outstanding_route_update_reqs_queued_stat, 1);
}
}
} else {
outstanding_++;
assert(outstanding_ <= maxOutstanding_);
}
SCOPE_EXIT {
if (!blockedRequests_.empty()) {
auto entry = std::move(blockedRequests_.front());
blockedRequests_.pop_front();
assert(!entry->batons.empty());
entry->batons.front()->post();
entry->batons.pop_front();
if (!entry->batons.empty()) {
blockedRequests_.push_back(std::move(entry));
} else {
senderIdToEntry_.erase(entry->senderId);
}
} else {
outstanding_--;
}
};
return target_->route(req);
}