9 #ifndef FAIR_MQ_TOOLS_RATELIMIT_H
10 #define FAIR_MQ_TOOLS_RATELIMIT_H
19 namespace fair::mq::tools
37 using clock = std::chrono::steady_clock;
48 : tw_req(std::chrono::seconds(1))
49 , start_time(clock::now())
52 tw_req = std::chrono::nanoseconds(1);
54 tw_req = std::chrono::duration_cast<clock::duration>(tw_req / rate);
56 skip_check_count = std::max(1,
int(std::chrono::milliseconds(5) / tw_req));
57 count = skip_check_count;
70 using namespace std::chrono;
72 auto now = clock::now();
73 if (tw == clock::duration::zero()) {
74 tw = (now - start_time) / skip_check_count;
76 tw = (1 * tw + 3 * (now - start_time) / skip_check_count) / 4;
81 if (tw > tw_req * 65 / 64) {
85 if (ts > clock::duration::zero()) {
86 ts = std::max(clock::duration::zero(), ts - (tw - tw_req) * skip_check_count * 1 / 2);
91 std::min(
int(seconds(1) / tw_req),
92 (skip_check_count * 5 + 3) / 4);
96 }
else if (tw < tw_req * 63 / 64) {
105 const int min_skip_count = std::max(1,
int(milliseconds(5) / tw_req));
106 if (skip_check_count > min_skip_count) {
107 assert(ts == clock::duration::zero());
108 skip_check_count = std::max(min_skip_count, skip_check_count * 3 / 4);
112 ts += (tw_req - tw) * (skip_check_count * 7) / 8;
119 count = skip_check_count;
120 if (ts > clock::duration::zero()) {
121 std::this_thread::sleep_for(ts);
127 clock::duration tw{},
130 clock::time_point start_time;
132 int skip_check_count = 1;
137 #endif // FAIR_MQ_TOOLS_RATELIMIT_H