mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 22:04:56 +00:00
docs: rate,overview,limiter (2 files)
This commit is contained in:
@@ -1,89 +1,49 @@
|
||||
#pragma once
|
||||
/**
|
||||
* @file rate_limiter.hpp
|
||||
* @brief Token bucket rate limiter
|
||||
* @details Header-only, thread-safe rate limiting
|
||||
* @brief Token bucket rate limiter (thread-safe wrapper)
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include "rate_limit_try_acquire.hpp"
|
||||
#include "rate_limit_remaining.hpp"
|
||||
|
||||
namespace dbal::security {
|
||||
|
||||
/**
|
||||
* Thread-safe token bucket rate limiter
|
||||
* Wraps individual rate limit functions with mutex protection
|
||||
*/
|
||||
class RateLimiter {
|
||||
public:
|
||||
/**
|
||||
* @param tokens_per_second Refill rate
|
||||
* @param max_tokens Maximum bucket size (burst capacity)
|
||||
*/
|
||||
RateLimiter(double tokens_per_second, double max_tokens)
|
||||
: tokens_per_second_(tokens_per_second)
|
||||
, max_tokens_(max_tokens)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Try to consume a token for the given key
|
||||
* @param key Client identifier (IP, user ID, etc.)
|
||||
* @return true if allowed, false if rate limited
|
||||
*/
|
||||
bool try_acquire(const std::string& key) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
auto& bucket = buckets_[key];
|
||||
|
||||
// Initialize new buckets
|
||||
if (bucket.tokens == 0 && bucket.last_update.time_since_epoch().count() == 0) {
|
||||
bucket.tokens = max_tokens_;
|
||||
bucket.last_update = now;
|
||||
}
|
||||
|
||||
// Refill tokens based on elapsed time
|
||||
auto elapsed = std::chrono::duration<double>(now - bucket.last_update).count();
|
||||
bucket.tokens = std::min(max_tokens_, bucket.tokens + elapsed * tokens_per_second_);
|
||||
bucket.last_update = now;
|
||||
|
||||
// Try to consume
|
||||
if (bucket.tokens >= 1.0) {
|
||||
bucket.tokens -= 1.0;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return rate_limit_try_acquire(buckets_[key], tokens_per_second_, max_tokens_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get remaining tokens for a key
|
||||
*/
|
||||
double remaining(const std::string& key) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto it = buckets_.find(key);
|
||||
if (it == buckets_.end()) return max_tokens_;
|
||||
return it->second.tokens;
|
||||
return rate_limit_remaining(it->second, max_tokens_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset a specific key's bucket
|
||||
*/
|
||||
void reset(const std::string& key) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
buckets_.erase(key);
|
||||
}
|
||||
|
||||
private:
|
||||
struct Bucket {
|
||||
double tokens = 0;
|
||||
std::chrono::steady_clock::time_point last_update{};
|
||||
};
|
||||
|
||||
double tokens_per_second_;
|
||||
double max_tokens_;
|
||||
std::unordered_map<std::string, Bucket> buckets_;
|
||||
std::unordered_map<std::string, TokenBucket> buckets_;
|
||||
std::mutex mutex_;
|
||||
};
|
||||
|
||||
|
||||
@@ -55,6 +55,9 @@ The database manages the following entity types:
|
||||
- `code`: Lua source code
|
||||
- `parameters`: Array of parameter definitions
|
||||
- `returnType`: Expected return type
|
||||
- `isSandboxed`: Whether script runs in sandbox
|
||||
- `allowedGlobals`: Allowed global functions/modules
|
||||
- `timeoutMs`: Execution timeout in milliseconds
|
||||
|
||||
#### Pages
|
||||
- **Key**: `db_pages`
|
||||
|
||||
Reference in New Issue
Block a user