Composable rate limiting algorithms for MoonBit applications
let limiter = @moonlimit.TokenBucket::new(2, 1, 1000)
let decision = limiter.allow_at(0)
inspect(decision.is_allowed(), content="true")fn BatchTokenBucket::new(capacity : Int, refill_tokens : Int, refill_period_ms : Int) -> BatchTokenBucketpub(all) struct CompositeLimiter {
token_buckets : Array[TokenBucket]
fixed_windows : Array[FixedWindow]
} derive(Debug)fn CompositeLimiter::add_fixed_window(self : CompositeLimiter, limit : Int, window_ms : Int) -> Unitfn CompositeLimiter::add_token_bucket(self : CompositeLimiter, capacity : Int, refill_tokens : Int, refill_period_ms : Int) -> Unitpub(all) struct DecisionStats {
allowed_count : Int
rejected_count : Int
retry_after_total_ms : Int
retry_after_max_ms : Int
} derive(Debug)pub(all) struct EngineRule {
rule_name : String
kind : LimitKind
token_bucket : TokenBucket
fixed_window : FixedWindow
sliding_log : SlidingLog
quota_window : QuotaWindow
} derive(Debug)fn EngineRule::token_bucket(name : String, capacity : Int, refill_tokens : Int, refill_period_ms : Int) -> EngineRulepub(all) struct FixedWindow {
limit : Int
window_ms : Int
window_start_ms : Int
used : Int
} derive(Debug)pub(all) struct Gcra {
interval_ms : Int
burst_capacity : Int
theoretical_arrival_ms : Int
} derive(Debug)pub(all) struct KeyedConcurrencyLimiter {
capacity : Int
states : HashMap[String, ConcurrencyLimiter]
} derive(Debug)pub(all) struct KeyedFixedWindow {
limit : Int
window_ms : Int
windows : HashMap[String, FixedWindow]
last_seen : HashMap[String, Int]
} derive(Debug)fn KeyedFixedWindow::allow_at(self : KeyedFixedWindow, key : String, now_ms : Int, cost? : Int) -> Decisionpub(all) struct KeyedSlidingLog {
limit : Int
window_ms : Int
logs : HashMap[String, SlidingLog]
last_seen : HashMap[String, Int]
} derive(Debug)fn KeyedSlidingLog::allow_at(self : KeyedSlidingLog, key : String, now_ms : Int, cost? : Int) -> Decisionpub(all) struct KeyedTokenBucket {
capacity : Int
refill_tokens : Int
refill_period_ms : Int
buckets : HashMap[String, TokenBucket]
last_seen : HashMap[String, Int]
} derive(Debug)fn KeyedTokenBucket::allow_at(self : KeyedTokenBucket, key : String, now_ms : Int, cost? : Int) -> Decisionfn KeyedTokenBucket::new(capacity : Int, refill_tokens : Int, refill_period_ms : Int) -> KeyedTokenBucketpub(all) struct LeakyBucket {
capacity : Int
leak_tokens : Int
leak_period_ms : Int
level : Int
last_leak_ms : Int
} derive(Debug)fn LeakyBucket::new(capacity : Int, leak_tokens : Int, leak_period_ms : Int, start_ms? : Int) -> LeakyBucketpub(all) struct LimiterRecipe {
recipe_name : String
audience : String
engine : PolicyEngine
workload : Workload
} derive(Debug)fn PolicyEngine::add_fixed_window(self : PolicyEngine, name : String, limit : Int, window_ms : Int) -> Unitfn PolicyEngine::add_quota(self : PolicyEngine, name : String, quota : Int, period_ms : Int) -> Unitfn PolicyEngine::add_sliding_log(self : PolicyEngine, name : String, limit : Int, window_ms : Int) -> Unitfn PolicyEngine::add_token_bucket(self : PolicyEngine, name : String, capacity : Int, refill_tokens : Int, refill_period_ms : Int) -> Unitpub(all) struct QuotaWindow {
quota : Int
period_ms : Int
window_start_ms : Int
used : Int
} derive(Debug)pub(all) struct SimulationReport {
trace : Array[TraceEntry]
allowed_count : Int
rejected_count : Int
} derive(Debug)pub(all) struct Simulator {
}pub(all) struct SlidingWindow {
limit : Int
window_ms : Int
window_start_ms : Int
current_count : Int
previous_count : Int
} derive(Debug)pub(all) struct TokenBucket {
capacity : Int
refill_tokens : Int
refill_period_ms : Int
tokens : Int
last_refill_ms : Int
} derive(Debug)fn TokenBucket::new(capacity : Int, refill_tokens : Int, refill_period_ms : Int, start_ms? : Int) -> TokenBucketpub(all) struct WarmupTokenBucket {
capacity : Int
refill_tokens : Int
refill_period_ms : Int
warmup_ms : Int
start_ms : Int
tokens : Int
last_refill_ms : Int
} derive(Debug)fn WarmupTokenBucket::new(capacity : Int, refill_tokens : Int, refill_period_ms : Int, warmup_ms : Int, start_ms? : Int) -> WarmupTokenBucketComposable rate limiting algorithms for MoonBit applications