#pragma once #include #include #include #include namespace mosis { struct RateLimitConfig { double tokens_per_second; // Refill rate double max_tokens; // Bucket capacity }; class RateLimiter { public: // Default limits for common operations RateLimiter(); // Check if operation is allowed (consumes token if yes) bool Check(const std::string& app_id, const std::string& operation); // Check without consuming token bool CanProceed(const std::string& app_id, const std::string& operation) const; // Configure limits for an operation void SetLimit(const std::string& operation, const RateLimitConfig& config); // Get config for an operation const RateLimitConfig* GetLimit(const std::string& operation) const; // Get current token count for app+operation double GetTokens(const std::string& app_id, const std::string& operation) const; // Reset all buckets for an app (e.g., on app restart) void ResetApp(const std::string& app_id); // Clear all buckets void ClearAll(); private: struct Bucket { double tokens; std::chrono::steady_clock::time_point last_refill; }; // Refill bucket based on elapsed time void Refill(Bucket& bucket, const RateLimitConfig& config) const; // Get or create bucket for app+operation Bucket& GetBucket(const std::string& app_id, const std::string& operation); // Get bucket key static std::string MakeKey(const std::string& app_id, const std::string& operation); mutable std::mutex m_mutex; std::unordered_map m_configs; mutable std::unordered_map m_buckets; }; // Global rate limiter (singleton) RateLimiter& GetRateLimiter(); } // namespace mosis // Convenience alias using RateLimiter = mosis::RateLimiter; using RateLimitConfig = mosis::RateLimitConfig;