2#ifndef _KURLYK_HTTP_RATE_LIMITER_HPP_INCLUDED
3#define _KURLYK_HTTP_RATE_LIMITER_HPP_INCLUDED
25 std::lock_guard<std::mutex> lock(
m_mutex);
31 std::chrono::steady_clock::now()
41 std::lock_guard<std::mutex> lock(
m_mutex);
52 bool allow_request(
long general_rate_limit_id,
long specific_rate_limit_id) {
53 std::lock_guard<std::mutex> lock(
m_mutex);
54 auto general_it =
m_limits.find(general_rate_limit_id);
55 auto specific_it =
m_limits.find(specific_rate_limit_id);
57 specific_it ==
m_limits.end())
return true;
59 auto now = std::chrono::steady_clock::now();
60 bool general_limit_allowed =
true;
61 bool specific_limit_allowed =
true;
64 auto& limit_data = general_it->second;
65 general_limit_allowed =
check_limit(limit_data, now);
69 auto& limit_data = specific_it->second;
70 specific_limit_allowed =
check_limit(limit_data, now);
73 if (general_limit_allowed && specific_limit_allowed) {
76 auto& limit_data = general_it->second;
80 auto& limit_data = specific_it->second;
99 template<
typename Duration = std::chrono::milliseconds>
101 std::lock_guard<std::mutex> lock(
m_mutex);
102 auto now = std::chrono::steady_clock::now();
103 Duration max_delay{0};
105 auto it =
m_limits.find(general_rate_limit_id);
110 it =
m_limits.find(specific_rate_limit_id);
125 template<
typename Duration = std::chrono::milliseconds>
127 std::lock_guard<std::mutex> lock(
m_mutex);
128 auto now = std::chrono::steady_clock::now();
130 Duration min_delay = Duration::max();
133 const auto& limit = pair.second;
135 if (delay.count() > 0 && delay < min_delay) {
140 return (min_delay == Duration::max()) ? Duration{0} : min_delay;
164 auto elapsed_time = std::chrono::duration_cast<std::chrono::milliseconds>(now - limit_data.
start_time);
167 if (elapsed_time.count() >= limit_data.
period_ms) {
183 auto elapsed_time = std::chrono::duration_cast<std::chrono::milliseconds>(now - limit_data.
start_time);
186 if (elapsed_time.count() >= limit_data.
period_ms) {
188 limit_data.
count = 0;
203 template<
typename Duration>
206 auto elapsed = std::chrono::duration_cast<Duration>(now - limit_data.
start_time);
207 auto period_duration = std::chrono::duration_cast<Duration>(std::chrono::milliseconds(limit_data.
period_ms));
208 if (elapsed >= period_duration ||
212 return period_duration - elapsed;
Manages rate limits for HTTP requests, ensuring compliance with set limits.
std::unordered_map< long, LimitData > m_limits
Map storing rate limit configurations.
bool remove_limit(long limit_id)
Removes a rate limit with the specified ID.
bool allow_request(long general_rate_limit_id, long specific_rate_limit_id)
Checks if a request is allowed under the specified general and specific rate limits.
std::chrono::steady_clock::time_point time_point_t
long m_next_id
Next available unique ID for rate limits.
Duration time_until_next_allowed(long general_rate_limit_id, long specific_rate_limit_id)
Calculates the delay until the next request is allowed under the specified rate limits.
bool check_limit(LimitData &limit_data, const time_point_t &now)
Checks if a request is allowed under the specified rate limit without updating the count.
Duration time_until_any_limit_allows()
Finds the shortest delay among all active rate limits.
void update_limit(LimitData &limit_data, const time_point_t &now)
Updates the request count for the specified rate limit.
long create_limit(long requests_per_period, long period_ms)
Creates a new rate limit with specified parameters.
Duration time_until_limit_allows(const LimitData &limit_data, const time_point_t &now) const
Calculates the delay required before a request is allowed under a single rate limit.
std::mutex m_mutex
Mutex to protect shared data.
Primary namespace for the Kurlyk library, encompassing initialization, request management,...
Stores data for an individual rate limit.
time_point_t start_time
Start time of the current rate period.
long count
Requests made in the current period.
long requests_per_period
Max requests allowed in the period.
long period_ms
Duration of the period in milliseconds.