userver: userver/utils/token_bucket.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
token_bucket.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/utils/token_bucket.hpp
4/// @brief @copybrief utils::TokenBucket
5
6#include <atomic>
7#include <chrono>
8
9USERVER_NAMESPACE_BEGIN
10
11namespace utils {
12
13/// @ingroup userver_universal userver_concurrency
14///
15/// Thread safe ratelimiter
16class TokenBucket final {
17 public:
18 using TimePoint = std::chrono::steady_clock::time_point;
19 using Duration = std::chrono::steady_clock::duration;
20
21 /// Token bucket refill policy
22 struct RefillPolicy {
23 /// Refill amount (zero disables refills)
25 /// Refill interval (zero makes bucket to instantly refill)
26 Duration interval{Duration::max()};
27 };
28
29 /// Create an initially always empty token bucket
30 TokenBucket() noexcept;
31
32 /// Create a token bucket with max_size tokens and a specified refill policy
33 TokenBucket(size_t max_size, RefillPolicy policy);
34
35 /// Start with max_size tokens and add 1 token each
36 /// single_token_update_interval up to max_size.
37 /// Zero duration means "no limit".
38 [[deprecated]] TokenBucket(size_t max_size,
39 Duration single_token_update_interval);
40
41 /// Create an initially unbounded token bucket (largest size, instant refill)
42 static TokenBucket MakeUnbounded() noexcept;
43
44 TokenBucket(const TokenBucket&) = delete;
45 TokenBucket(TokenBucket&&) noexcept;
46 TokenBucket& operator=(const TokenBucket&) = delete;
47 TokenBucket& operator=(TokenBucket&&) noexcept;
48
49 bool IsUnbounded() const;
50
51 /// Get current token limit (might be inaccurate as the result is stale)
53
54 /// Get current refill amount (might be inaccurate as the result is stale)
56
57 /// Get current refill interval (might be inaccurate as the result is stale)
58 Duration GetRefillIntervalApprox() const;
59
60 /// Get rate (tokens per second)
61 double GetRatePs() const;
62
63 /// Get current token count (might be inaccurate as the result is stale)
65
66 /// Set max token count
67 void SetMaxSize(size_t max_size);
68
69 /// Add 1 token each token_update_interval.
70 /// Zero duration means "no limit".
71 [[deprecated]] void SetUpdateInterval(Duration single_token_update_interval);
72
73 /// Set refill policy for the bucket
75
76 /// Set refill policy to "instant refill".
77 ///
78 /// Obtain does not deplete the bucket in this mode.
79 /// Equivalent to `amount=1, interval=zero()` policy.
81
82 /// @returns true if token was successfully obtained
83 [[nodiscard]] bool Obtain();
84
85 /// @return true if the requested number of tokens was successfully obtained
86 [[nodiscard]] bool ObtainAll(size_t count);
87
88 /// Get rate for specified update interval (updates per second)
89 static double GetRatePs(Duration interval);
90
91 private:
92 void Update();
93
94 std::atomic<size_t> max_size_;
95 std::atomic<size_t> token_refill_amount_;
96 std::atomic<Duration> token_refill_interval_;
97 std::atomic<size_t> tokens_;
98 std::atomic<TimePoint> last_update_;
99};
100
101} // namespace utils
102
103USERVER_NAMESPACE_END