1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
#include "throttler.hpp"
namespace fz::http::client {
void request_throttler::throttle(std::string const& hostname, datetime const& backoff)
{
if (hostname.empty() || !backoff) {
return;
}
scoped_lock l(mtx_);
bool found{};
auto now = datetime::now();
for (size_t i = 0; i < backoff_.size(); ) {
auto & entry = backoff_[i];
if (entry.first == hostname) {
found = true;
if (entry.second < backoff) {
entry.second = backoff;
}
}
if (entry.second < now) {
backoff_[i] = std::move(backoff_.back());
backoff_.pop_back();
}
else {
++i;
}
}
if (!found) {
backoff_.emplace_back(hostname, backoff);
}
}
duration request_throttler::get_throttle(std::string const& hostname)
{
scoped_lock l(mtx_);
duration ret;
auto now = datetime::now();
for (size_t i = 0; i < backoff_.size(); ) {
auto & entry = backoff_[i];
if (entry.second < now) {
backoff_[i] = std::move(backoff_.back());
backoff_.pop_back();
}
else {
if (entry.first == hostname) {
ret = entry.second - now;
}
++i;
}
}
return ret;
}
}
|