RateLimiter¶
Thread-safe token bucket rate limiter for controlling request/operation frequency.
Quick Start¶
#include "lrvx/util/rate_limiter.h"
// 10 requests per second
RateLimiter limiter({.capacity = 10, .refillRate = 10});
if (limiter.tryAcquire()) {
sendRequest();
} else {
// Rate limit exceeded
}
Use Cases¶
- API rate limiting — prevent exchange bans
- Log throttling — avoid log spam
- Alert throttling — limit notification frequency
- Order frequency — cap orders per second
API¶
Constructor¶
RateLimiter(Config config);
struct Config {
uint32_t capacity; // Maximum tokens in bucket
uint32_t refillRate; // Tokens added per second; 0 means "never refills"
};
A refillRate of 0 is a valid configuration, not an error: the bucket becomes
a fixed burst budget of exactly capacity tokens, and only reset() brings
them back. timeUntilAvailable() then answers Duration::max() — "never" —
rather than a finite time nobody will ever reach.
// 5 calls, ever, until the caller decides to reset
RateLimiter budget({.capacity = 5, .refillRate = 0});
Methods¶
| Method | Description |
|---|---|
tryAcquire(n) |
Try to consume n tokens. Returns true if successful. |
timeUntilAvailable(n) |
Duration until n tokens will be available. Duration::max() means never: the bucket does not refill, or n exceeds capacity. |
available() |
Current token count. |
reset() |
Reset to full capacity. |
capacity() |
Maximum tokens. |
refillRate() |
Tokens per second. |
Examples¶
Exchange Connector¶
class BybitOrderExecutor : public IOrderExecutor {
public:
BybitOrderExecutor()
: _orderLimiter({.capacity = 10, .refillRate = 10}) // 10 orders/sec
{}
void submitOrder(const Order& order) override {
if (!_orderLimiter.tryAcquire()) {
reject(order, "rate limit exceeded");
return;
}
sendToExchange(order);
}
private:
RateLimiter _orderLimiter;
};
Wait for Availability¶
if (!limiter.tryAcquire()) {
auto wait = limiter.timeUntilAvailable();
std::this_thread::sleep_for(wait);
limiter.tryAcquire(); // Should succeed now
}
Multiple Token Operations¶
Log Throttling¶
class ThrottledLogger {
public:
ThrottledLogger() : _limiter({.capacity = 10, .refillRate = 1}) {} // 1/sec burst 10
void warn(const std::string& msg) {
if (_limiter.tryAcquire()) {
std::cerr << "[WARN] " << msg << "\n";
}
}
private:
RateLimiter _limiter;
};
Algorithm¶
Token bucket with continuous refill:
- Tokens accumulate at
refillRateper second - Bucket holds maximum
capacitytokens tryAcquire(n)consumes n tokens if available- Lock-free implementation using atomics
Thread Safety¶
All methods are thread-safe and lock-free. Safe for concurrent use from multiple threads.
See Also¶
- IKillSwitch — emergency shutdown