moonlimit

Composable rate limiting algorithms for MoonBit applications

rate-limit
token-bucket
gcra
moonbit
throttling
moon add RunnerQuan/moonlimit@0.1.1
Download zip
Version
0.1.1
License
Apache-2.0
Last updated
last month
Downloads
35
README

#MoonLimit

Composable rate limiting algorithms for MoonBit applications.

MoonLimit currently includes token bucket, leaky bucket, fixed window, sliding window, sliding log, GCRA, warmup token bucket, quota window, concurrency, keyed variants, policy engines, simulation helpers, and cookbook recipes.

let limiter = @moonlimit.TokenBucket::new(2, 1, 1000)
let decision = limiter.allow_at(0)
inspect(decision.is_allowed(), content="true")

#
AdmissionMode

pub(all) enum AdmissionMode {
AllOf
AnyOf
} derive(Eq,
Debug
)

#
AlgorithmDoc

pub(all) struct AlgorithmDoc {
doc_name : String
summary : String
strengths : String
tradeoffs : String
} derive(Eq,
Debug
)

#
AlgorithmDoc::line

fn AlgorithmDoc::line(self : AlgorithmDoc) -> String

#
AlgorithmDoc::markdown

fn AlgorithmDoc::markdown(self : AlgorithmDoc) -> String

#
AlgorithmDoc::name

fn AlgorithmDoc::name(self : AlgorithmDoc) -> String

#
AllowInfo

pub(all) struct AllowInfo {
remaining : Int
reset_after_ms : Int
} derive(Eq,
Debug
)

Successful admission details returned by a limiter.

#
BatchDecision

pub(all) struct BatchDecision {
decisions : Array[Decision]
} derive(
Debug
)

#
BatchDecision::all_allowed

fn BatchDecision::all_allowed(self : BatchDecision) -> Bool

#
BatchDecision::allowed

fn BatchDecision::allowed(self : BatchDecision) -> Int

#
BatchDecision::len

fn BatchDecision::len(self : BatchDecision) -> Int

#
BatchDecision::max_retry_after_ms

fn BatchDecision::max_retry_after_ms(self : BatchDecision) -> Int

#
BatchDecision::new

#
BatchDecision::push

fn BatchDecision::push(self : BatchDecision, decision : Decision) -> Unit

#
BatchDecision::rejected

fn BatchDecision::rejected(self : BatchDecision) -> Int

#
BatchTokenBucket

pub(all) struct BatchTokenBucket {
bucket : TokenBucket
} derive(
Debug
)

#
BatchTokenBucket::allow_many

fn BatchTokenBucket::allow_many(self : BatchTokenBucket, times : Array[Int]) -> BatchDecision

#
BatchTokenBucket::new

fn BatchTokenBucket::new(capacity : Int, refill_tokens : Int, refill_period_ms : Int) -> BatchTokenBucket

#
CompositeLimiter

pub(all) struct CompositeLimiter {
token_buckets : Array[TokenBucket]
fixed_windows : Array[FixedWindow]
} derive(
Debug
)

#
CompositeLimiter::add_fixed_window

fn CompositeLimiter::add_fixed_window(self : CompositeLimiter, limit : Int, window_ms : Int) -> Unit

#
CompositeLimiter::add_token_bucket

fn CompositeLimiter::add_token_bucket(self : CompositeLimiter, capacity : Int, refill_tokens : Int, refill_period_ms : Int) -> Unit

#
CompositeLimiter::all

#
CompositeLimiter::allow_at

fn CompositeLimiter::allow_at(self : CompositeLimiter, now_ms : Int) -> Decision

#
ConcurrencyLimiter

pub(all) struct ConcurrencyLimiter {
capacity : Int
in_flight : Int
} derive(
Debug
)

#
ConcurrencyLimiter::acquire

#
ConcurrencyLimiter::in_use

fn ConcurrencyLimiter::in_use(self : ConcurrencyLimiter) -> Int

#
ConcurrencyLimiter::new

fn ConcurrencyLimiter::new(capacity : Int) -> ConcurrencyLimiter

#
ConcurrencyLimiter::release

fn ConcurrencyLimiter::release(self : ConcurrencyLimiter) -> Bool

#
CookbookEntry

pub(all) struct CookbookEntry {
entry_name : String
description : String
spec : LimitSpec
} derive(Eq,
Debug
)

#
CookbookEntry::name

fn CookbookEntry::name(self : CookbookEntry) -> String

#
CookbookEntry::summary

fn CookbookEntry::summary(self : CookbookEntry) -> String

#
Decision

pub(all) enum Decision {
Allowed(AllowInfo)
Rejected(RejectInfo)
} derive(Eq,
Debug
)

Rate limiter decision with enough context for logs, tests, and clients.

#
Decision::explain

fn Decision::explain(self : Decision) -> String

#
Decision::is_allowed

fn Decision::is_allowed(self : Decision) -> Bool

#
Decision::remaining

fn Decision::remaining(self : Decision) -> Int

#
Decision::reset_after_ms

fn Decision::reset_after_ms(self : Decision) -> Int

#
Decision::retry_after_ms

fn Decision::retry_after_ms(self : Decision) -> Int

#
DecisionStats

pub(all) struct DecisionStats {
allowed_count : Int
rejected_count : Int
retry_after_total_ms : Int
retry_after_max_ms : Int
} derive(
Debug
)

#
DecisionStats::allowed

fn DecisionStats::allowed(self : DecisionStats) -> Int

#
DecisionStats::average_retry_after_ms

fn DecisionStats::average_retry_after_ms(self : DecisionStats) -> Int

#
DecisionStats::max_retry_after_ms

fn DecisionStats::max_retry_after_ms(self : DecisionStats) -> Int

#
DecisionStats::new

#
DecisionStats::record

fn DecisionStats::record(self : DecisionStats, decision : Decision) -> Unit

#
DecisionStats::rejected

fn DecisionStats::rejected(self : DecisionStats) -> Int

#
DecisionStats::summary

fn DecisionStats::summary(self : DecisionStats) -> String

#
DecisionStats::total

fn DecisionStats::total(self : DecisionStats) -> Int

#
Duration

pub(all) struct Duration {
value_ms : Int
} derive(Eq,
Debug
)

#
Duration::from_millis

fn Duration::from_millis(value_ms : Int) -> Duration

#
Duration::millis

fn Duration::millis(self : Duration) -> Int

#
Duration::parse

fn Duration::parse(text : String) -> Duration

#
Duration::seconds

fn Duration::seconds(self : Duration) -> Int

#
EngineRule

pub(all) struct EngineRule {
rule_name : String
kind : LimitKind
token_bucket : TokenBucket
fixed_window : FixedWindow
sliding_log : SlidingLog
quota_window : QuotaWindow
} derive(
Debug
)

#
EngineRule::allow_at

fn EngineRule::allow_at(self : EngineRule, now_ms : Int, cost? : Int) -> Decision

#
EngineRule::describe

fn EngineRule::describe(self : EngineRule) -> String

#
EngineRule::fixed_window

fn EngineRule::fixed_window(name : String, limit : Int, window_ms : Int) -> EngineRule

#
EngineRule::kind_name

fn EngineRule::kind_name(self : EngineRule) -> String

#
EngineRule::name

fn EngineRule::name(self : EngineRule) -> String

#
EngineRule::quota

fn EngineRule::quota(name : String, quota : Int, period_ms : Int) -> EngineRule

#
EngineRule::sliding_log

fn EngineRule::sliding_log(name : String, limit : Int, window_ms : Int) -> EngineRule

#
EngineRule::token_bucket

fn EngineRule::token_bucket(name : String, capacity : Int, refill_tokens : Int, refill_period_ms : Int) -> EngineRule

#
FixedWindow

pub(all) struct FixedWindow {
limit : Int
window_ms : Int
window_start_ms : Int
used : Int
} derive(
Debug
)

#
FixedWindow::allow_at

fn FixedWindow::allow_at(self : FixedWindow, now_ms : Int, cost? : Int) -> Decision

#
FixedWindow::new

fn FixedWindow::new(limit : Int, window_ms : Int, start_ms? : Int) -> FixedWindow

#
Gcra

pub(all) struct Gcra {
interval_ms : Int
burst_capacity : Int
theoretical_arrival_ms : Int
} derive(
Debug
)

#
Gcra::allow_at

fn Gcra::allow_at(self : Gcra, now_ms : Int, cost? : Int) -> Decision

#
Gcra::new

fn Gcra::new(limit : Int, period_ms : Int, burst_capacity? : Int, start_ms? : Int) -> Gcra

#
KeyedConcurrencyLimiter

pub(all) struct KeyedConcurrencyLimiter {
capacity : Int
states :
HashMap
[String, ConcurrencyLimiter]
} derive(
Debug
)

#
KeyedConcurrencyLimiter::acquire

fn KeyedConcurrencyLimiter::acquire(self : KeyedConcurrencyLimiter, key : String) -> Decision

#
KeyedConcurrencyLimiter::in_use

fn KeyedConcurrencyLimiter::in_use(self : KeyedConcurrencyLimiter, key : String) -> Int

#
KeyedConcurrencyLimiter::len

#
KeyedConcurrencyLimiter::new

#
KeyedConcurrencyLimiter::release

fn KeyedConcurrencyLimiter::release(self : KeyedConcurrencyLimiter, key : String) -> Bool

#
KeyedFixedWindow

pub(all) struct KeyedFixedWindow {
limit : Int
window_ms : Int
windows :
HashMap
[String, FixedWindow]
last_seen :
HashMap
[String, Int]
} derive(
Debug
)

#
KeyedFixedWindow::allow_at

fn KeyedFixedWindow::allow_at(self : KeyedFixedWindow, key : String, now_ms : Int, cost? : Int) -> Decision

#
KeyedFixedWindow::len

fn KeyedFixedWindow::len(self : KeyedFixedWindow) -> Int

#
KeyedFixedWindow::new

fn KeyedFixedWindow::new(limit : Int, window_ms : Int) -> KeyedFixedWindow

#
KeyedFixedWindow::prune_idle

fn KeyedFixedWindow::prune_idle(self : KeyedFixedWindow, now_ms : Int, max_idle_ms : Int) -> Int

#
KeyedGcra

pub(all) struct KeyedGcra {
limit : Int
period_ms : Int
burst_capacity : Int
states :
HashMap
[String, Gcra]
last_seen :
HashMap
[String, Int]
} derive(
Debug
)

#
KeyedGcra::allow_at

fn KeyedGcra::allow_at(self : KeyedGcra, key : String, now_ms : Int, cost? : Int) -> Decision

#
KeyedGcra::len

fn KeyedGcra::len(self : KeyedGcra) -> Int

#
KeyedGcra::new

fn KeyedGcra::new(limit : Int, period_ms : Int, burst_capacity? : Int) -> KeyedGcra

#
KeyedGcra::prune_idle

fn KeyedGcra::prune_idle(self : KeyedGcra, now_ms : Int, max_idle_ms : Int) -> Int

#
KeyedSlidingLog

pub(all) struct KeyedSlidingLog {
limit : Int
window_ms : Int
logs :
HashMap
[String, SlidingLog]
last_seen :
HashMap
[String, Int]
} derive(
Debug
)

#
KeyedSlidingLog::allow_at

fn KeyedSlidingLog::allow_at(self : KeyedSlidingLog, key : String, now_ms : Int, cost? : Int) -> Decision

#
KeyedSlidingLog::len

fn KeyedSlidingLog::len(self : KeyedSlidingLog) -> Int

#
KeyedSlidingLog::new

fn KeyedSlidingLog::new(limit : Int, window_ms : Int) -> KeyedSlidingLog

#
KeyedSlidingLog::prune_idle

fn KeyedSlidingLog::prune_idle(self : KeyedSlidingLog, now_ms : Int, max_idle_ms : Int) -> Int

#
KeyedTokenBucket

pub(all) struct KeyedTokenBucket {
capacity : Int
refill_tokens : Int
refill_period_ms : Int
buckets :
HashMap
[String, TokenBucket]
last_seen :
HashMap
[String, Int]
} derive(
Debug
)

#
KeyedTokenBucket::allow_at

fn KeyedTokenBucket::allow_at(self : KeyedTokenBucket, key : String, now_ms : Int, cost? : Int) -> Decision

#
KeyedTokenBucket::len

fn KeyedTokenBucket::len(self : KeyedTokenBucket) -> Int

#
KeyedTokenBucket::new

fn KeyedTokenBucket::new(capacity : Int, refill_tokens : Int, refill_period_ms : Int) -> KeyedTokenBucket

#
KeyedTokenBucket::prune_idle

fn KeyedTokenBucket::prune_idle(self : KeyedTokenBucket, now_ms : Int, max_idle_ms : Int) -> Int

#
LeakyBucket

pub(all) struct LeakyBucket {
capacity : Int
leak_tokens : Int
leak_period_ms : Int
level : Int
last_leak_ms : Int
} derive(
Debug
)

#
LeakyBucket::allow_at

fn LeakyBucket::allow_at(self : LeakyBucket, now_ms : Int, cost? : Int) -> Decision

#
LeakyBucket::new

fn LeakyBucket::new(capacity : Int, leak_tokens : Int, leak_period_ms : Int, start_ms? : Int) -> LeakyBucket

#
LimitKind

pub(all) enum LimitKind {
TokenBucket
FixedWindow
SlidingLog
GcraSpec
} derive(Eq,
Debug
)

#
LimitSpec

pub(all) struct LimitSpec {
kind : LimitKind
spec_name : String
first : Int
second : Int
third : Int
} derive(Eq,
Debug
)

#
LimitSpec::explain

fn LimitSpec::explain(self : LimitSpec) -> String

#
LimitSpec::fixed_window

fn LimitSpec::fixed_window(name : String, limit : Int, window_ms : Int) -> LimitSpec

#
LimitSpec::kind_name

fn LimitSpec::kind_name(self : LimitSpec) -> String

#
LimitSpec::name

fn LimitSpec::name(self : LimitSpec) -> String

#
LimitSpec::parse

fn LimitSpec::parse(text : String) -> LimitSpec

#
LimitSpec::sliding_log

fn LimitSpec::sliding_log(name : String, limit : Int, window_ms : Int) -> LimitSpec

#
LimitSpec::to_fixed_window

fn LimitSpec::to_fixed_window(self : LimitSpec) -> FixedWindow

#
LimitSpec::to_sliding_log

fn LimitSpec::to_sliding_log(self : LimitSpec) -> SlidingLog

#
LimitSpec::to_token_bucket

fn LimitSpec::to_token_bucket(self : LimitSpec) -> TokenBucket

#
LimitSpec::token_bucket

fn LimitSpec::token_bucket(name : String, capacity : Int, refill_tokens : Int, refill_period_ms : Int) -> LimitSpec

#
LimitSpec::validate

fn LimitSpec::validate(self : LimitSpec) -> ValidationReport

#
LimiterRecipe

pub(all) struct LimiterRecipe {
recipe_name : String
audience : String
engine : PolicyEngine
workload : Workload
} derive(
Debug
)

#
LimiterRecipe::describe

fn LimiterRecipe::describe(self : LimiterRecipe) -> String

#
LimiterRecipe::name

fn LimiterRecipe::name(self : LimiterRecipe) -> String

#
LimiterRecipe::run

#
ParseError

pub(all) struct ParseError {
field : String
message : String
} derive(Eq,
Debug
)

#
ParseError::field

fn ParseError::field(self : ParseError) -> String

#
ParseError::message

fn ParseError::message(self : ParseError) -> String

#
ParseError::new

fn ParseError::new(field : String, message : String) -> ParseError

#
ParseResult

pub(all) enum ParseResult {
ParseOk(LimitSpec)
ParseFailed(ParseError)
} derive(Eq,
Debug
)

#
ParseResult::error_field

fn ParseResult::error_field(self : ParseResult) -> String

#
ParseResult::error_message

fn ParseResult::error_message(self : ParseResult) -> String

#
ParseResult::is_ok

fn ParseResult::is_ok(self : ParseResult) -> Bool

#
ParseResult::parse_limit

fn ParseResult::parse_limit(text : String) -> ParseResult

#
ParseResult::spec

fn ParseResult::spec(self : ParseResult) -> LimitSpec

#
PolicyEngine

pub(all) struct PolicyEngine {
mode : AdmissionMode
rules : Array[EngineRule]
} derive(
Debug
)

#
PolicyEngine::add_fixed_window

fn PolicyEngine::add_fixed_window(self : PolicyEngine, name : String, limit : Int, window_ms : Int) -> Unit

#
PolicyEngine::add_quota

fn PolicyEngine::add_quota(self : PolicyEngine, name : String, quota : Int, period_ms : Int) -> Unit

#
PolicyEngine::add_rule

fn PolicyEngine::add_rule(self : PolicyEngine, rule : EngineRule) -> Unit

#
PolicyEngine::add_sliding_log

fn PolicyEngine::add_sliding_log(self : PolicyEngine, name : String, limit : Int, window_ms : Int) -> Unit

#
PolicyEngine::add_token_bucket

fn PolicyEngine::add_token_bucket(self : PolicyEngine, name : String, capacity : Int, refill_tokens : Int, refill_period_ms : Int) -> Unit

#
PolicyEngine::all

#
PolicyEngine::allow_at

fn PolicyEngine::allow_at(self : PolicyEngine, now_ms : Int, cost? : Int) -> Decision

#
PolicyEngine::any

#
PolicyEngine::describe

fn PolicyEngine::describe(self : PolicyEngine) -> String

#
PolicyEngine::len

fn PolicyEngine::len(self : PolicyEngine) -> Int

#
PolicyEngine::simulate

fn PolicyEngine::simulate(self : PolicyEngine, workload : Workload) -> SimulationReport

#
QuotaWindow

pub(all) struct QuotaWindow {
quota : Int
period_ms : Int
window_start_ms : Int
used : Int
} derive(
Debug
)

#
QuotaWindow::allow_at

fn QuotaWindow::allow_at(self : QuotaWindow, now_ms : Int, cost? : Int) -> Decision

#
QuotaWindow::new

fn QuotaWindow::new(quota : Int, period_ms : Int, start_ms? : Int) -> QuotaWindow

#
QuotaWindow::remaining_quota

fn QuotaWindow::remaining_quota(self : QuotaWindow) -> Int

#
QuotaWindow::used

fn QuotaWindow::used(self : QuotaWindow) -> Int

#
Rate

pub(all) struct Rate {
count : Int
period : Duration
} derive(Eq,
Debug
)

#
Rate::events

fn Rate::events(self : Rate) -> Int

#
Rate::new

fn Rate::new(count : Int, period : Duration) -> Rate

#
Rate::parse

fn Rate::parse(text : String) -> Rate

#
Rate::period_ms

fn Rate::period_ms(self : Rate) -> Int

#
RejectInfo

pub(all) struct RejectInfo {
retry_after_ms : Int
reason : String
} derive(Eq,
Debug
)

Rejection details returned by a limiter.

#
RequestEvent

pub(all) struct RequestEvent {
at_ms : Int
cost : Int
key : String
} derive(Eq,
Debug
)

#
RetryAdvice

pub(all) struct RetryAdvice {
should_retry : Bool
wait_ms : Int
message : String
} derive(Eq,
Debug
)

#
RetryAdvice::from_decision

fn RetryAdvice::from_decision(decision : Decision) -> RetryAdvice

#
RetryAdvice::message

fn RetryAdvice::message(self : RetryAdvice) -> String

#
RetryAdvice::should_retry

fn RetryAdvice::should_retry(self : RetryAdvice) -> Bool

#
RetryAdvice::wait_ms

fn RetryAdvice::wait_ms(self : RetryAdvice) -> Int

#
RetrySchedule

pub(all) struct RetrySchedule {
base_ms : Int
max_ms : Int
factor : Int
} derive(Eq,
Debug
)

#
RetrySchedule::delay_at

fn RetrySchedule::delay_at(self : RetrySchedule, attempt : Int) -> Int

#
RetrySchedule::delays

fn RetrySchedule::delays(self : RetrySchedule, attempts : Int) -> Array[Int]

#
RetrySchedule::describe

fn RetrySchedule::describe(self : RetrySchedule, attempts : Int) -> String

#
RetrySchedule::exponential

fn RetrySchedule::exponential(base_ms : Int, max_ms : Int, factor? : Int) -> RetrySchedule

#
RuleSet

pub(all) struct RuleSet {
specs : Array[LimitSpec]
} derive(
Debug
)

#
RuleSet::get

fn RuleSet::get(self : RuleSet, index : Int) -> LimitSpec?

#
RuleSet::len

fn RuleSet::len(self : RuleSet) -> Int

#
RuleSet::new

fn RuleSet::new() -> RuleSet

#
RuleSet::parse_lines

fn RuleSet::parse_lines(text : String) -> RuleSet

#
RuleSet::push

fn RuleSet::push(self : RuleSet, spec : LimitSpec) -> Unit

#
RuleSet::validate

fn RuleSet::validate(self : RuleSet) -> ValidationReport

#
Severity

pub(all) enum Severity {
Info
Warning
Error
} derive(Eq,
Debug
)

#
SimulationReport

pub(all) struct SimulationReport {
trace : Array[TraceEntry]
allowed_count : Int
rejected_count : Int
} derive(
Debug
)

#
SimulationReport::allowed

fn SimulationReport::allowed(self : SimulationReport) -> Int

#
SimulationReport::allowed_per_thousand

fn SimulationReport::allowed_per_thousand(self : SimulationReport) -> Int

#
SimulationReport::csv

fn SimulationReport::csv(self : SimulationReport) -> String

#
SimulationReport::max_retry_after_ms

fn SimulationReport::max_retry_after_ms(self : SimulationReport) -> Int

#
SimulationReport::new

#
SimulationReport::record

fn SimulationReport::record(self : SimulationReport, at_ms : Int, decision : Decision) -> Unit

#
SimulationReport::rejected

fn SimulationReport::rejected(self : SimulationReport) -> Int

#
SimulationReport::rejected_per_thousand

fn SimulationReport::rejected_per_thousand(self : SimulationReport) -> Int

#
SimulationReport::summary_line

fn SimulationReport::summary_line(self : SimulationReport) -> String

#
SimulationReport::total

fn SimulationReport::total(self : SimulationReport) -> Int

#
Simulator

pub(all) struct Simulator {
}

#
Simulator::run_fixed_window

fn Simulator::run_fixed_window(limiter : FixedWindow, workload : Workload) -> SimulationReport

#
Simulator::run_token_bucket

fn Simulator::run_token_bucket(limiter : TokenBucket, workload : Workload) -> SimulationReport

#
SlidingLog

pub(all) struct SlidingLog {
limit : Int
window_ms : Int
events : Array[Int]
} derive(
Debug
)

#
SlidingLog::allow_at

fn SlidingLog::allow_at(self : SlidingLog, now_ms : Int, cost? : Int) -> Decision

#
SlidingLog::len

fn SlidingLog::len(self : SlidingLog) -> Int

#
SlidingLog::new

fn SlidingLog::new(limit : Int, window_ms : Int) -> SlidingLog

#
SlidingWindow

pub(all) struct SlidingWindow {
limit : Int
window_ms : Int
window_start_ms : Int
current_count : Int
previous_count : Int
} derive(
Debug
)

#
SlidingWindow::allow_at

fn SlidingWindow::allow_at(self : SlidingWindow, now_ms : Int, cost? : Int) -> Decision

#
SlidingWindow::new

fn SlidingWindow::new(limit : Int, window_ms : Int, start_ms? : Int) -> SlidingWindow

#
TokenBucket

pub(all) struct TokenBucket {
capacity : Int
refill_tokens : Int
refill_period_ms : Int
tokens : Int
last_refill_ms : Int
} derive(
Debug
)

#
TokenBucket::allow_at

fn TokenBucket::allow_at(self : TokenBucket, now_ms : Int, cost? : Int) -> Decision

#
TokenBucket::new

fn TokenBucket::new(capacity : Int, refill_tokens : Int, refill_period_ms : Int, start_ms? : Int) -> TokenBucket

#
TraceEntry

pub(all) struct TraceEntry {
at_ms : Int
decision : Decision
} derive(
Debug
)

#
ValidationIssue

pub(all) struct ValidationIssue {
severity : Severity
field : String
message : String
} derive(Eq,
Debug
)

#
ValidationIssue::error

fn ValidationIssue::error(field : String, message : String) -> ValidationIssue

#
ValidationIssue::field

fn ValidationIssue::field(self : ValidationIssue) -> String

#
ValidationIssue::info

fn ValidationIssue::info(field : String, message : String) -> ValidationIssue

#
ValidationIssue::is_error

fn ValidationIssue::is_error(self : ValidationIssue) -> Bool

#
ValidationIssue::message

fn ValidationIssue::message(self : ValidationIssue) -> String

#
ValidationIssue::warning

fn ValidationIssue::warning(field : String, message : String) -> ValidationIssue

#
ValidationReport

pub(all) struct ValidationReport {
issues : Array[ValidationIssue]
} derive(
Debug
)

#
ValidationReport::error_count

fn ValidationReport::error_count(self : ValidationReport) -> Int

#
ValidationReport::is_ok

fn ValidationReport::is_ok(self : ValidationReport) -> Bool

#
ValidationReport::len

fn ValidationReport::len(self : ValidationReport) -> Int

#
ValidationReport::new

#
ValidationReport::push

fn ValidationReport::push(self : ValidationReport, issue : ValidationIssue) -> Unit

#
ValidationReport::summary

fn ValidationReport::summary(self : ValidationReport) -> String

#
ValidationReport::warning_count

fn ValidationReport::warning_count(self : ValidationReport) -> Int

#
WarmupTokenBucket

pub(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
)

#
WarmupTokenBucket::allow_at

fn WarmupTokenBucket::allow_at(self : WarmupTokenBucket, now_ms : Int, cost? : Int) -> Decision

#
WarmupTokenBucket::capacity_at

fn WarmupTokenBucket::capacity_at(self : WarmupTokenBucket, now_ms : Int) -> Int

#
WarmupTokenBucket::new

fn WarmupTokenBucket::new(capacity : Int, refill_tokens : Int, refill_period_ms : Int, warmup_ms : Int, start_ms? : Int) -> WarmupTokenBucket

#
Workload

pub(all) struct Workload {
events : Array[RequestEvent]
} derive(
Debug
)

#
Workload::alternating_keys

fn Workload::alternating_keys(count : Int, start_ms : Int, step_ms : Int, left : String, right : String) -> Workload

#
Workload::burst

fn Workload::burst(count : Int, at_ms : Int) -> Workload

#
Workload::describe

fn Workload::describe(self : Workload) -> String

#
Workload::first_at

fn Workload::first_at(self : Workload) -> Int

#
Workload::last_at

fn Workload::last_at(self : Workload) -> Int

#
Workload::len

fn Workload::len(self : Workload) -> Int

#
Workload::merge

fn Workload::merge(left : Workload, right : Workload) -> Workload

#
Workload::new

fn Workload::new() -> Workload

#
Workload::push

fn Workload::push(self : Workload, at_ms : Int, cost? : Int, key? : String) -> Unit

#
Workload::ramp

fn Workload::ramp(count : Int, start_ms : Int, initial_step_ms : Int, decrement_ms : Int) -> Workload

#
Workload::repeat

fn Workload::repeat(self : Workload, times : Int, spacing_ms : Int) -> Workload

#
Workload::shift

fn Workload::shift(self : Workload, delta_ms : Int) -> Workload

#
Workload::steady

fn Workload::steady(count : Int, start_ms : Int, step_ms : Int) -> Workload

#
algorithm_docs

fn algorithm_docs() -> Array[AlgorithmDoc]

#
algorithm_markdown

fn algorithm_markdown() -> String

#
algorithm_summary_table

fn algorithm_summary_table() -> String

#
ceil_div

fn ceil_div(numerator : Int, denominator : Int) -> Int

#
clamp_non_negative

fn clamp_non_negative(value : Int) -> Int

#
cookbook_admin_api

fn cookbook_admin_api() -> CookbookEntry

#
cookbook_ai_inference

fn cookbook_ai_inference() -> CookbookEntry

#
cookbook_audit_export

fn cookbook_audit_export() -> CookbookEntry

#
cookbook_backup_job

fn cookbook_backup_job() -> CookbookEntry

#
cookbook_billing_sync

fn cookbook_billing_sync() -> CookbookEntry

#
cookbook_checkout_flow

fn cookbook_checkout_flow() -> CookbookEntry

#
cookbook_comment_posting

fn cookbook_comment_posting() -> CookbookEntry

#
cookbook_count

fn cookbook_count() -> Int

#
cookbook_crawler_host

fn cookbook_crawler_host() -> CookbookEntry

#
cookbook_download_endpoint

fn cookbook_download_endpoint() -> CookbookEntry

#
cookbook_email_worker

fn cookbook_email_worker() -> CookbookEntry

#
cookbook_embedding_job

fn cookbook_embedding_job() -> CookbookEntry

#
cookbook_entries

fn cookbook_entries() -> Array[CookbookEntry]

#
cookbook_feed_refresh

fn cookbook_feed_refresh() -> CookbookEntry

#
cookbook_find

fn cookbook_find(name : String) -> CookbookEntry?

#
cookbook_image_worker

fn cookbook_image_worker() -> CookbookEntry

#
cookbook_log_ingest

fn cookbook_log_ingest() -> CookbookEntry

#
cookbook_login_endpoint

fn cookbook_login_endpoint() -> CookbookEntry

#
cookbook_markdown

fn cookbook_markdown() -> String

#
cookbook_message_sending

fn cookbook_message_sending() -> CookbookEntry

#
cookbook_metrics_ingest

fn cookbook_metrics_ingest() -> CookbookEntry

#
cookbook_notification_push

fn cookbook_notification_push() -> CookbookEntry

#
cookbook_password_reset_endpoint

fn cookbook_password_reset_endpoint() -> CookbookEntry

#
cookbook_payment_attempts

fn cookbook_payment_attempts() -> CookbookEntry

#
cookbook_public_api_edge

fn cookbook_public_api_edge() -> CookbookEntry

#
cookbook_report_worker

fn cookbook_report_worker() -> CookbookEntry

#
cookbook_search_typeahead

fn cookbook_search_typeahead() -> CookbookEntry

#
cookbook_signup_endpoint

fn cookbook_signup_endpoint() -> CookbookEntry

#
cookbook_sms_worker

fn cookbook_sms_worker() -> CookbookEntry

#
cookbook_tenant_plan_free

fn cookbook_tenant_plan_free() -> CookbookEntry

#
cookbook_tenant_plan_pro

fn cookbook_tenant_plan_pro() -> CookbookEntry

#
cookbook_thumbnail_job

fn cookbook_thumbnail_job() -> CookbookEntry

#
cookbook_upload_endpoint

fn cookbook_upload_endpoint() -> CookbookEntry

#
cookbook_webhook_worker

fn cookbook_webhook_worker() -> CookbookEntry

#
doc_concurrency

fn doc_concurrency() -> AlgorithmDoc

#
doc_fixed_window

fn doc_fixed_window() -> AlgorithmDoc

#
doc_gcra

fn doc_gcra() -> AlgorithmDoc

#
doc_leaky_bucket

fn doc_leaky_bucket() -> AlgorithmDoc

#
doc_quota

fn doc_quota() -> AlgorithmDoc

#
doc_sliding_log

fn doc_sliding_log() -> AlgorithmDoc

#
doc_sliding_window

fn doc_sliding_window() -> AlgorithmDoc

#
doc_token_bucket

fn doc_token_bucket() -> AlgorithmDoc

#
recipe_all

fn recipe_all() -> Array[LimiterRecipe]

#
recipe_api_gateway

fn recipe_api_gateway() -> LimiterRecipe

#
recipe_batch_import

fn recipe_batch_import() -> LimiterRecipe

#
recipe_checkout_guard

fn recipe_checkout_guard() -> LimiterRecipe

#
recipe_crawler_politeness

fn recipe_crawler_politeness() -> LimiterRecipe

#
recipe_email_sender

fn recipe_email_sender() -> LimiterRecipe

#
recipe_image_renderer

fn recipe_image_renderer() -> LimiterRecipe

#
recipe_login_guard

fn recipe_login_guard() -> LimiterRecipe

#
recipe_markdown_index

fn recipe_markdown_index() -> String

#
recipe_names

fn recipe_names() -> Array[String]

#
recipe_password_reset

fn recipe_password_reset() -> LimiterRecipe

fn recipe_search_box() -> LimiterRecipe

#
recipe_sms_sender

fn recipe_sms_sender() -> LimiterRecipe

#
recipe_tenant_fairness

fn recipe_tenant_fairness() -> LimiterRecipe

#
recipe_webhook_dispatch

fn recipe_webhook_dispatch() -> LimiterRecipe