#include "SlidingWindowRateLimiter.h" #include using namespace drogon; SlidingWindowRateLimiter::SlidingWindowRateLimiter( size_t capacity, std::chrono::duration timeUnit) : capacity_(capacity), unitStartTime_(std::chrono::steady_clock::now()), lastTime_(unitStartTime_), timeUnit_(timeUnit) { } // implementation of the sliding window algorithm bool SlidingWindowRateLimiter::isAllowed() { auto now = std::chrono::steady_clock::now(); unitStartTime_ = unitStartTime_ + std::chrono::duration_cast( std::chrono::duration( static_cast( (uint64_t)(std::chrono::duration_cast< std::chrono::duration>( now - unitStartTime_) .count() / timeUnit_.count())) * timeUnit_.count())); if (unitStartTime_ > lastTime_) { auto duration = std::chrono::duration_cast>( unitStartTime_ - lastTime_); auto startTime = lastTime_; if (duration >= timeUnit_) { previousRequests_ = 0; } else { previousRequests_ = currentRequests_; } currentRequests_ = 0; } auto coef = std::chrono::duration_cast>( now - unitStartTime_) / timeUnit_; assert(coef <= 1.0); auto count = previousRequests_ * (1.0 - coef) + currentRequests_; if (count < capacity_) { currentRequests_++; lastTime_ = now; return true; } return false; }