1 // Copyright 2004-present Facebook. All Rights Reserved.
2 
3 #pragma once
4 
5 #include <quic/server/RateLimiter.h>
6 
7 namespace quic {
8 
9 /*
10  * Simple "sliding window" rate limiter. This enforces a rate limit of count
11  * events per window. The window "slides" by multiplying the average rate of
12  * the previous full window by the amount of time that the current sliding
13  * window occurred in the previous window.
14  * E.g.
15  * Limit of 100 events per 10s. The previous window had 50 events. The current
16  * window has had 5 events. We check an event 3 seconds into our current
17  * window. The sliding window has 3 seconds in our current window, and 7
18  * seconds in the previous window. We psuedo-count for the current sliding
19  * window is: 50/10 * 7 + 5 + 1 = 41.
20  */
21 class SlidingWindowRateLimiter : public RateLimiter {
22  public:
SlidingWindowRateLimiter(std::function<uint64_t ()> count,std::chrono::seconds window)23   SlidingWindowRateLimiter(
24       std::function<uint64_t()> count,
25       std::chrono::seconds window)
26       : count_(std::move(count)), window_(window) {}
27 
28   bool check(TimePoint time) override;
29 
30  private:
31   const std::function<uint64_t()> count_;
32   const std::chrono::microseconds window_;
33   folly::Optional<TimePoint> currentWindowStartPoint_{folly::none};
34   uint64_t countInPrevWindow_{0};
35   uint64_t countInCurWindow_{0};
36 };
37 
38 } // namespace quic
39