moonresilience

A pure MoonBit resilience toolkit for retry, circuit breaking, rate limiting, bulkhead isolation, telemetry, and deterministic simulation.

resilience
retry
circuit-breaker
rate-limiter
bulkhead
moon add liying-han/moonresilience@0.2.0
Download zip
Version
0.2.0
License
Apache-2.0
Last updated
4 hours ago
Downloads
2
README

#MoonResilience

MoonResilience 是一个使用 MoonBit 编写的弹性治理基础库,用于服务调用、后台任务、消息消费和基础工具中的故障隔离与恢复。项目不绑定 HTTP 框架和系统时钟,调用方可以按需要接入现有应用。

#功能范围

  • Retry:固定、线性、指数、序列退避;支持最大次数、时间预算、错误码过滤和不可重试错误。
  • Circuit Breaker:Closed、Open、HalfOpen 状态机;支持恢复窗口、探测并发限制、成功阈值和状态快照。
  • Rate Limiter:token bucket 与 fixed window;返回剩余配额、拒绝原因和建议重试时间。
  • Bulkhead:并发槽位、有限等待队列、FIFO 晋升、取消和容量快照。
  • Policy Chain:按照限流、隔离、熔断、重试的固定顺序执行,并保留可检查的执行轨迹。
  • Telemetry:有界事件日志、计数指标、延迟分桶和 Prometheus 文本导出。
  • Configkey=value 配置解析、默认值、字段校验和错误行定位。
  • Simulation:显式时间和预设故障响应,不进行真实等待即可验证策略行为。

当前版本包含约 4.5k 行有效 MoonBit 代码和 100 项测试。核心包没有第三方依赖。

#仓库

两个仓库同步发布,默认分支为 master

#快速开始

环境要求:已安装当前稳定版 MoonBit 工具链。

moon check moon test moon run cmd/main

CLI 会运行一个“上游连续两次超时、第三次恢复”的确定性场景,并输出尝试次数、虚拟时间线和指标摘要。

#基本用法

let chain = @moonresilience.policy_chain(
@moonresilience.retry_policy(
4,
5000,
@moonresilience.exponential_backoff(100, 1000),
["timeout"],
),
@moonresilience.new_circuit_breaker(
@moonresilience.circuit_breaker_config(4, 1, 2000, 1),
),
TokenBucketPolicy(
@moonresilience.new_token_bucket(
@moonresilience.token_bucket_config(20, 20, 1000),
0,
),
),
@moonresilience.new_bulkhead(
@moonresilience.bulkhead_config(4, 8),
),
)

let result = @moonresilience.execute_with(
chain,
@moonresilience.execution_context(0, "inventory.query"),
fn(attempt, _now_ms) {
if attempt < 3 {
Failure(@moonresilience.retryable_failure("timeout", "upstream timeout"))
} else {
Success("ok")
}
},
)

配置方式参见 examples/resilience.conf,完整接口说明参见 docs/API.md。接入网络客户端前请阅读 docs/HTTP_ADAPTER.md 中的错误分类和状态保存说明。

#执行顺序

execute_with 使用固定顺序,便于预测资源消耗和拒绝原因:

  1. 限流器申请一个许可;
  2. Bulkhead 申请执行槽位;
  3. 熔断器判断调用是否允许;
  4. 执行动作,失败时由 RetryPolicy 判断是否重试;
  5. 更新熔断器并释放 Bulkhead 槽位。

同步执行入口不会等待 Bulkhead 队列。进入等待队列时会返回 RejectedByBulkhead,调用方可使用独立调度器处理排队请求。

#配置

retry.max_attempts=4 retry.max_elapsed_ms=5000 retry.backoff=exponential retry.base_delay_ms=100 retry.max_delay_ms=1000 breaker.failure_threshold=4 breaker.success_threshold=1 breaker.open_window_ms=2000 limiter.kind=token_bucket limiter.capacity=20 limiter.refill_tokens=20 limiter.window_ms=1000 bulkhead.max_concurrent=4 bulkhead.max_waiting=8

parse_config 会忽略空行和以 # 开头的注释。未知字段、非整数值和约束冲突会返回带行号的 ConfigError

#项目结构

. ├── retry.mbt # 重试与退避 ├── circuit_breaker.mbt # 熔断器状态机 ├── rate_limiter.mbt # 两类限流器 ├── bulkhead.mbt # 并发隔离与等待队列 ├── policy_chain.mbt # 统一执行入口 ├── telemetry.mbt # 事件与计数指标 ├── latency.mbt # 延迟分桶 ├── metrics_export.mbt # Prometheus 文本导出 ├── config.mbt # 配置解析与校验 ├── simulation.mbt # 确定性故障模拟 ├── diagnostics.mbt # 健康状态与不变量检查 ├── registry.mbt # 命名策略目录 ├── batch.mbt # 批量场景执行 ├── cmd/main # 可运行示例 └── docs # API、架构与比赛材料

#开发与验证

moon info moon fmt moon check --warn-list +73 moon test moon run cmd/main moon coverage analyze

提交代码前请阅读 CONTRIBUTING.md。版本变化记录在 CHANGELOG.md,后续工作记录在 ROADMAP.md

#当前边界

  • 项目提供与框架无关的策略内核,不直接发起网络请求。
  • 时间由调用方显式传入;生产接入层需要提供实际时钟。
  • 当前执行入口为同步模型,等待队列只维护调度状态。
  • 配置解析器面向小型本地配置,不替代通用配置文件格式。

#许可证

Apache-2.0,详见 LICENSE

#
ActionOutcome

pub(all) enum ActionOutcome[T] {
Success(T)
Failure(AttemptFailure)
}

#
AttemptFailure

pub(all) struct AttemptFailure {
code : String
message : String
retryable : Bool
} derive(Eq)

#
BackoffStrategy

pub(all) enum BackoffStrategy {
Fixed(Int)
Exponential(Int, Int)
Linear(Int, Int, Int)
Sequence(Array[Int])
} derive(Eq,
Debug
)

#
BatchItemResult

pub(all) struct BatchItemResult {
id : String
result : SimulationResult
} derive(
Debug
)

#
BatchRequest

pub(all) struct BatchRequest {
id : String
scenario : SimulationScenario
} derive(Eq,
Debug
)

#
BatchResult

pub(all) struct BatchResult {
items : Array[BatchItemResult]
final_chain : PolicyChain
stopped_early : Bool
} derive(
Debug
)

#
BatchSummary

pub(all) struct BatchSummary {
total : Int
succeeded : Int
failed : Int
attempts : Int
virtual_duration_ms : Int
stopped_early : Bool
} derive(Eq,
Debug
)

#
BreakerDecision

pub(all) enum BreakerDecision {
BreakerAllowed(CircuitBreaker, Bool)
BreakerRejected(CircuitBreaker, Int, String)
} derive(Eq,
Debug
)

#
BreakerSnapshot

pub(all) struct BreakerSnapshot {
state : BreakerState
consecutive_failures : Int
half_open_successes : Int
half_open_in_flight : Int
open_until_ms : Int
remaining_open_ms : Int
transition_count : Int
} derive(Eq,
Debug
)

#
BreakerState

pub(all) enum BreakerState {
Closed
Open
HalfOpen
} derive(Eq,
Debug
)

#
Bulkhead

pub(all) struct Bulkhead {
config : BulkheadConfig
active_calls : Array[String]
waiting_calls : Array[WaitingCall]
total_entered : Int
total_queued : Int
total_rejected : Int
total_completed : Int
} derive(Eq,
Debug
)

#
BulkheadAdmission

pub(all) enum BulkheadAdmission {
BulkheadEntered(Bulkhead, Int)
BulkheadQueued(Bulkhead, Int)
BulkheadRejected(Bulkhead, String)
} derive(Eq,
Debug
)

#
BulkheadConfig

pub(all) struct BulkheadConfig {
max_concurrent : Int
max_waiting : Int
} derive(Eq,
Debug
)

#
BulkheadRelease

pub(all) struct BulkheadRelease {
bulkhead : Bulkhead
released : Bool
promoted_call : String?
} derive(Eq,
Debug
)

#
BulkheadSnapshot

pub(all) struct BulkheadSnapshot {
active : Int
waiting : Int
available : Int
waiting_available : Int
total_entered : Int
total_queued : Int
total_rejected : Int
total_completed : Int
} derive(Eq,
Debug
)

#
CircuitBreaker

pub(all) struct CircuitBreaker {
config : CircuitBreakerConfig
state : BreakerState
consecutive_failures : Int
half_open_successes : Int
half_open_in_flight : Int
opened_at_ms : Int
open_until_ms : Int
transition_count : Int
} derive(Eq,
Debug
)

#
CircuitBreakerConfig

pub(all) struct CircuitBreakerConfig {
failure_threshold : Int
success_threshold : Int
open_window_ms : Int
half_open_max_calls : Int
} derive(Eq,
Debug
)

#
ConfigError

pub(all) enum ConfigError {
InvalidConfigLine(Int, String)
UnknownConfigKey(Int, String)
InvalidConfigValue(Int, String, String)
ConfigConstraint(String, String)
} derive(Eq,
Debug
)

#
EventKind

pub(all) enum EventKind {
ExecutionStarted
ExecutionSucceeded
ExecutionFailed
RetryScheduledEvent
CircuitOpenedEvent
CircuitHalfOpenedEvent
CircuitClosedEvent
RateLimitGrantedEvent
RateLimitRejectedEvent
BulkheadEnteredEvent
BulkheadQueuedEvent
BulkheadRejectedEvent
BulkheadReleasedEvent
} derive(Eq,
Debug
)

#
EventLog

pub(all) struct EventLog {
events : Array[ResilienceEvent]
max_events : Int
dropped_events : Int
} derive(Eq,
Debug
)

#
ExecuteError

pub(all) enum ExecuteError {
RejectedByRateLimiter(String)
RejectedByCircuitBreaker(Int)
RejectedByBulkhead(String)
RetryExhausted(String, String, Int)
InvalidPolicy(String)
} derive(Eq,
Debug
)

#
ExecutionContext

pub(all) struct ExecutionContext {
now_ms : Int
operation : String
tags : Array[Tag]
} derive(Eq)

#
ExecutionResult

pub(all) struct ExecutionResult[T] {
outcome : Result[T, ExecuteError]
chain : PolicyChain
attempts : Int
started_at_ms : Int
finished_at_ms : Int
trace : ExecutionTrace
}

#
ExecutionTrace

pub(all) struct ExecutionTrace {
steps : Array[String]
} derive(Eq,
Debug
)

#
FixedWindowConfig

pub(all) struct FixedWindowConfig {
limit : Int
window_ms : Int
} derive(Eq,
Debug
)

#
FixedWindowLimiter

pub(all) struct FixedWindowLimiter {
config : FixedWindowConfig
window_started_ms : Int
used : Int
total_granted : Int
total_rejected : Int
} derive(Eq,
Debug
)

#
FixedWindowResult

pub(all) struct FixedWindowResult {
limiter : FixedWindowLimiter
decision : RateLimitDecision
} derive(Eq,
Debug
)

#
HealthLevel

pub(all) enum HealthLevel {
Healthy
Degraded
Unavailable
} derive(Eq,
Debug
)

#
InvariantViolation

pub(all) struct InvariantViolation {
component : String
message : String
} derive(Eq,
Debug
)

#
LatencyBucket

pub(all) struct LatencyBucket {
upper_bound_ms : Int
count : Int
} derive(Eq,
Debug
)

#
LatencyHistogram

pub(all) struct LatencyHistogram {
buckets : Array[LatencyBucket]
overflow_count : Int
total_count : Int
total_ms : Int
min_ms : Int
max_ms : Int
} derive(Eq,
Debug
)

#
LatencySnapshot

pub(all) struct LatencySnapshot {
count : Int
average_ms : Int
min_ms : Int
max_ms : Int
p50_ms : Int
p90_ms : Int
p99_ms : Int
buckets : Array[LatencyBucket]
overflow_count : Int
} derive(Eq,
Debug
)

#
MetricCounter

pub(all) struct MetricCounter {
name : String
value : Int
} derive(Eq,
Debug
)

#
MetricLabel

pub(all) struct MetricLabel {
name : String
value : String
} derive(Eq,
Debug
)

#
Metrics

pub(all) struct Metrics {
counters : Array[MetricCounter]
latency_count : Int
latency_total_ms : Int
latency_max_ms : Int
} derive(Eq,
Debug
)

#
MetricsSnapshot

pub(all) struct MetricsSnapshot {
executions : Int
successes : Int
failures : Int
retries : Int
circuit_opens : Int
rate_limit_rejections : Int
bulkhead_rejections : Int
average_latency_ms : Int
max_latency_ms : Int
custom : Array[MetricCounter]
} derive(Eq,
Debug
)

#
NamedPolicy

pub(all) struct NamedPolicy {
name : String
chain : PolicyChain
description : String
} derive(Eq,
Debug
)

#
PolicyChain

pub(all) struct PolicyChain {
retry : RetryPolicy
breaker : CircuitBreaker
rate_limit : RateLimitPolicy
bulkhead : Bulkhead
} derive(Eq,
Debug
)

#
PolicyRegistry

pub(all) struct PolicyRegistry {
policies : Array[NamedPolicy]
default_name : String?
} derive(Eq,
Debug
)

#
PolicySnapshot

pub(all) struct PolicySnapshot {
at_ms : Int
health : HealthLevel
breaker : BreakerSnapshot
limiter_kind : String
limiter_remaining : Int
limiter_retry_after_ms : Int
bulkhead : BulkheadSnapshot
violations : Array[InvariantViolation]
} derive(Eq,
Debug
)

#
RateLimitDecision

pub(all) struct RateLimitDecision {
allowed : Bool
remaining : Int
retry_after_ms : Int
reason : String
} derive(Eq,
Debug
)

#
RateLimitPolicy

pub(all) enum RateLimitPolicy {
TokenBucketPolicy(TokenBucket)
FixedWindowPolicy(FixedWindowLimiter)
} derive(Eq,
Debug
)

#
RegistryError

pub(all) enum RegistryError {
EmptyPolicyName
DuplicatePolicyName(String)
PolicyNotFound(String)
DefaultPolicyNotFound(String)
} derive(Eq,
Debug
)

#
ResilienceConfig

pub(all) struct ResilienceConfig {
retry_max_attempts : Int
retry_max_elapsed_ms : Int
retry_backoff : String
retry_base_delay_ms : Int
retry_max_delay_ms : Int
breaker_failure_threshold : Int
breaker_success_threshold : Int
breaker_open_window_ms : Int
breaker_half_open_max_calls : Int
limiter_kind : String
limiter_capacity : Int
limiter_refill_tokens : Int
limiter_window_ms : Int
bulkhead_max_concurrent : Int
bulkhead_max_waiting : Int
} derive(Eq,
Debug
)

#
ResilienceEvent

pub(all) struct ResilienceEvent {
kind : EventKind
at_ms : Int
operation : String
detail : String
value : Int
} derive(Eq,
Debug
)

#
RetryPolicy

pub(all) struct RetryPolicy {
max_attempts : Int
max_elapsed_ms : Int
backoff : BackoffStrategy
retryable_codes : Array[String]
} derive(Eq,
Debug
)

#
RetrySnapshot

pub(all) struct RetrySnapshot {
attempt : Int
elapsed_ms : Int
next_delay_ms : Int
can_retry : Bool
stop_reason : String
} derive(Eq,
Debug
)

#
SimulatedResponse

pub(all) enum SimulatedResponse {
SimulatedSuccess(String, Int)
SimulatedFailure(String, String, Bool, Int)
} derive(Eq,
Debug
)

#
SimulationResult

pub(all) struct SimulationResult {
scenario : SimulationScenario
outcome : Result[String, ExecuteError]
chain : PolicyChain
attempts : Int
finished_at_ms : Int
timeline : Array[TimelineEntry]
events : EventLog
metrics : MetricsSnapshot
} derive(
Debug
)

#
SimulationScenario

pub(all) struct SimulationScenario {
name : String
operation : String
started_at_ms : Int
responses : Array[SimulatedResponse]
repeat_last : Bool
} derive(Eq,
Debug
)

#
Tag

pub(all) struct Tag {
key : String
value : String
} derive(Eq,
Debug
)

#
TimelineEntry

pub(all) struct TimelineEntry {
at_ms : Int
label : String
detail : String
} derive(Eq,
Debug
)

#
TokenBucket

pub(all) struct TokenBucket {
config : TokenBucketConfig
available_tokens : Int
last_refill_ms : Int
total_granted : Int
total_rejected : Int
} derive(Eq,
Debug
)

#
TokenBucketConfig

pub(all) struct TokenBucketConfig {
capacity : Int
refill_tokens : Int
refill_period_ms : Int
} derive(Eq,
Debug
)

#
TokenBucketResult

pub(all) struct TokenBucketResult {
bucket : TokenBucket
decision : RateLimitDecision
} derive(Eq,
Debug
)

#
VirtualClock

pub(all) struct VirtualClock {
now_ms : Int
advances : Int
} derive(Eq,
Debug
)

#
WaitingCall

pub(all) struct WaitingCall {
call_id : String
enqueued_at_ms : Int
} derive(Eq,
Debug
)

#
batch_failures

fn batch_failures(batch : BatchResult) -> Array[BatchItemResult]

#
batch_find

fn batch_find(batch : BatchResult, id : String) -> SimulationResult?

#
batch_request

fn batch_request(id : String, scenario : SimulationScenario) -> BatchRequest

#
batch_summary

fn batch_summary(batch : BatchResult) -> BatchSummary

#
breaker_before_call

fn breaker_before_call(breaker : CircuitBreaker, now_ms : Int) -> BreakerDecision

#
breaker_cancel_call

fn breaker_cancel_call(breaker : CircuitBreaker) -> CircuitBreaker

#
breaker_force_close

fn breaker_force_close(breaker : CircuitBreaker) -> CircuitBreaker

#
breaker_force_open

fn breaker_force_open(breaker : CircuitBreaker, now_ms : Int) -> CircuitBreaker

#
breaker_record_failure

fn breaker_record_failure(breaker : CircuitBreaker, now_ms : Int) -> CircuitBreaker

#
breaker_record_success

fn breaker_record_success(breaker : CircuitBreaker, _now_ms : Int) -> CircuitBreaker

#
breaker_snapshot

fn breaker_snapshot(breaker : CircuitBreaker, now_ms : Int) -> BreakerSnapshot

#
breaker_state_name

fn breaker_state_name(state : BreakerState) -> String

#
bulkhead_admit

fn bulkhead_admit(bulkhead : Bulkhead, call_id : String, now_ms : Int) -> BulkheadAdmission

#
bulkhead_cancel_waiting

fn bulkhead_cancel_waiting(bulkhead : Bulkhead, call_id : String) -> Bulkhead

#
bulkhead_complete

fn bulkhead_complete(bulkhead : Bulkhead, call_id : String) -> BulkheadRelease

#
bulkhead_config

fn bulkhead_config(max_concurrent : Int, max_waiting : Int) -> BulkheadConfig

#
bulkhead_contains

fn bulkhead_contains(bulkhead : Bulkhead, call_id : String) -> Bool

#
bulkhead_snapshot

fn bulkhead_snapshot(bulkhead : Bulkhead) -> BulkheadSnapshot

#
bulkhead_wait_ms

fn bulkhead_wait_ms(bulkhead : Bulkhead, call_id : String, now_ms : Int) -> Int?

#
check_policy_invariants

fn check_policy_invariants(chain : PolicyChain) -> Array[InvariantViolation]

#
circuit_breaker_config

fn circuit_breaker_config(failure_threshold : Int, success_threshold : Int, open_window_ms : Int, half_open_max_calls : Int) -> CircuitBreakerConfig

#
clock_advance

fn clock_advance(clock : VirtualClock, duration_ms : Int) -> VirtualClock

#
clock_advance_to

fn clock_advance_to(clock : VirtualClock, target_ms : Int) -> VirtualClock

#
config_to_policy_chain

fn config_to_policy_chain(config : ResilienceConfig, now_ms : Int) -> Result[PolicyChain, ConfigError]

#
context_with_tag

fn context_with_tag(context : ExecutionContext, key : String, value : String) -> ExecutionContext

#
default_bulkhead

fn default_bulkhead() -> Bulkhead

#
default_circuit_breaker

fn default_circuit_breaker() -> CircuitBreaker

#
default_config

fn default_config() -> ResilienceConfig

#
default_latency_histogram

fn default_latency_histogram() -> LatencyHistogram

#
default_policy_chain

fn default_policy_chain(now_ms : Int) -> PolicyChain

#
default_retry_policy

fn default_retry_policy() -> RetryPolicy

#
empty_execution_trace

fn empty_execution_trace() -> ExecutionTrace

#
event_kind_name

fn event_kind_name(kind : EventKind) -> String

#
event_log_clear

fn event_log_clear(log : EventLog) -> EventLog

#
event_log_filter

fn event_log_filter(log : EventLog, kind : EventKind) -> EventLog

#
execute_with

fn[T] execute_with(chain : PolicyChain, context : ExecutionContext, action : (Int, Int) -> ActionOutcome[T]) -> ExecutionResult[T]

#
execution_context

fn execution_context(now_ms : Int, operation : String) -> ExecutionContext

#
execution_duration_ms

fn[T] execution_duration_ms(result : ExecutionResult[T]) -> Int

#
execution_succeeded

fn[T] execution_succeeded(result : ExecutionResult[T]) -> Bool

#
execution_trace_text

fn execution_trace_text(trace : ExecutionTrace) -> String

#
exponential_backoff

fn exponential_backoff(base_delay_ms : Int, max_delay_ms : Int) -> BackoffStrategy

#
export_latency_prometheus

fn export_latency_prometheus(snapshot : LatencySnapshot, prefix? : String, labels? : Array[MetricLabel]) -> Result[String, String]

#
export_prometheus

fn export_prometheus(snapshot : MetricsSnapshot, prefix? : String, labels? : Array[MetricLabel]) -> Result[String, String]

#
fixed_backoff

fn fixed_backoff(delay_ms : Int) -> BackoffStrategy

#
fixed_window_acquire

fn fixed_window_acquire(limiter : FixedWindowLimiter, permits : Int, now_ms : Int) -> FixedWindowResult

#
fixed_window_config

fn fixed_window_config(limit : Int, window_ms : Int) -> FixedWindowConfig

#
fixed_window_reset

fn fixed_window_reset(limiter : FixedWindowLimiter, now_ms : Int) -> FixedWindowLimiter

#
format_batch_summary

fn format_batch_summary(summary : BatchSummary) -> String

#
format_breaker_snapshot

fn format_breaker_snapshot(snapshot : BreakerSnapshot) -> String

#
format_bulkhead_snapshot

fn format_bulkhead_snapshot(snapshot : BulkheadSnapshot) -> String

#
format_config

fn format_config(config : ResilienceConfig) -> String

#
format_config_error

fn format_config_error(error : ConfigError) -> String

#
format_event

fn format_event(event : ResilienceEvent) -> String

#
format_execute_error

fn format_execute_error(error : ExecuteError) -> String

#
format_invariant_violations

fn format_invariant_violations(violations : Array[InvariantViolation]) -> String

#
format_latency_snapshot

fn format_latency_snapshot(snapshot : LatencySnapshot) -> String

#
format_metrics_snapshot

fn format_metrics_snapshot(snapshot : MetricsSnapshot) -> String

#
format_policy_snapshot

fn format_policy_snapshot(snapshot : PolicySnapshot) -> String

#
format_rate_limit_decision

fn format_rate_limit_decision(decision : RateLimitDecision) -> String

#
format_registry_error

fn format_registry_error(error : RegistryError) -> String

#
format_simulation

fn format_simulation(result : SimulationResult) -> String

#
format_timeline

fn format_timeline(timeline : Array[TimelineEntry]) -> String

#
health_level_name

fn health_level_name(level : HealthLevel) -> String

#
inspect_policy_chain

fn inspect_policy_chain(chain : PolicyChain, now_ms : Int) -> PolicySnapshot

#
latency_merge

fn latency_merge(left : LatencyHistogram, right : LatencyHistogram) -> Result[LatencyHistogram, String]

#
latency_observe

fn latency_observe(histogram : LatencyHistogram, latency_ms : Int) -> LatencyHistogram

#
latency_percentile

fn latency_percentile(histogram : LatencyHistogram, percentile : Int) -> Int

#
latency_snapshot

fn latency_snapshot(histogram : LatencyHistogram) -> LatencySnapshot

#
linear_backoff

fn linear_backoff(initial_delay_ms : Int, step_ms : Int, max_delay_ms : Int) -> BackoffStrategy

#
metric_label

fn metric_label(name : String, value : String) -> MetricLabel

#
metrics_counter

fn metrics_counter(metrics : Metrics, name : String) -> Int

#
metrics_from_log

fn metrics_from_log(log : EventLog) -> Metrics

#
metrics_increment

fn metrics_increment(metrics : Metrics, name : String, amount : Int) -> Metrics

#
metrics_observe_latency

fn metrics_observe_latency(metrics : Metrics, latency_ms : Int) -> Metrics

#
metrics_record_event

fn metrics_record_event(metrics : Metrics, event : ResilienceEvent) -> Metrics

#
metrics_snapshot

fn metrics_snapshot(metrics : Metrics) -> MetricsSnapshot

#
new_bulkhead

fn new_bulkhead(config : BulkheadConfig) -> Bulkhead

#
new_circuit_breaker

fn new_circuit_breaker(config : CircuitBreakerConfig) -> CircuitBreaker

#
new_event_log

fn new_event_log(max_events : Int) -> EventLog

#
new_fixed_window_limiter

fn new_fixed_window_limiter(config : FixedWindowConfig, now_ms : Int) -> FixedWindowLimiter

#
new_latency_histogram

fn new_latency_histogram(upper_bounds_ms : Array[Int]) -> LatencyHistogram

#
new_metrics

fn new_metrics() -> Metrics

#
new_policy_registry

fn new_policy_registry() -> PolicyRegistry

#
new_token_bucket

fn new_token_bucket(config : TokenBucketConfig, now_ms : Int) -> TokenBucket

#
parse_config

fn parse_config(input : String) -> Result[ResilienceConfig, ConfigError]

#
permanent_failure

fn permanent_failure(code : String, message : String) -> AttemptFailure

#
policy_chain

fn policy_chain(retry : RetryPolicy, breaker : CircuitBreaker, rate_limit : RateLimitPolicy, bulkhead : Bulkhead) -> PolicyChain

#
record_event

fn record_event(log : EventLog, event : ResilienceEvent) -> EventLog

#
refill_token_bucket

fn refill_token_bucket(bucket : TokenBucket, now_ms : Int) -> TokenBucket

#
registry_add

fn registry_add(registry : PolicyRegistry, name : String, chain : PolicyChain, description? : String) -> Result[PolicyRegistry, RegistryError]

#
registry_contains

fn registry_contains(registry : PolicyRegistry, name : String) -> Bool

#
registry_default

fn registry_default(registry : PolicyRegistry) -> Result[PolicyChain, RegistryError]

#
registry_find

fn registry_find(registry : PolicyRegistry, name : String) -> Result[PolicyChain, RegistryError]

#
registry_names

fn registry_names(registry : PolicyRegistry) -> Array[String]

#
registry_remove

fn registry_remove(registry : PolicyRegistry, name : String) -> Result[PolicyRegistry, RegistryError]

#
registry_replace

fn registry_replace(registry : PolicyRegistry, name : String, chain : PolicyChain, description? : String) -> Result[PolicyRegistry, RegistryError]

#
registry_set_default

fn registry_set_default(registry : PolicyRegistry, name : String) -> Result[PolicyRegistry, RegistryError]

#
resilience_event

fn resilience_event(kind : EventKind, at_ms : Int, operation : String, detail : String, value : Int) -> ResilienceEvent

#
retry_delay

fn retry_delay(strategy : BackoffStrategy, attempt : Int) -> Int

#
retry_policy

fn retry_policy(max_attempts : Int, max_elapsed_ms : Int, backoff : BackoffStrategy, retryable_codes : Array[String]) -> RetryPolicy

#
retry_snapshot

fn retry_snapshot(policy : RetryPolicy, failure : AttemptFailure, attempt : Int, elapsed_ms : Int) -> RetrySnapshot

#
retryable_failure

fn retryable_failure(code : String, message : String) -> AttemptFailure

#
roll_fixed_window

fn roll_fixed_window(limiter : FixedWindowLimiter, now_ms : Int) -> FixedWindowLimiter

#
run_batch

fn run_batch(chain : PolicyChain, requests : Array[BatchRequest], stop_on_failure? : Bool) -> BatchResult

#
run_scenarios

fn run_scenarios(chain : PolicyChain, scenarios : Array[SimulationScenario]) -> Array[SimulationResult]

#
sequence_backoff

fn sequence_backoff(delays_ms : Array[Int]) -> BackoffStrategy

#
should_retry

fn should_retry(policy : RetryPolicy, failure : AttemptFailure, attempt : Int, elapsed_ms : Int) -> Bool

#
simulate

fn simulate(chain : PolicyChain, scenario : SimulationScenario) -> SimulationResult

#
simulated_failure

fn simulated_failure(code : String, message : String, retryable : Bool, latency_ms : Int) -> SimulatedResponse

#
simulated_success

fn simulated_success(value : String, latency_ms : Int) -> SimulatedResponse

#
simulation_duration_ms

fn simulation_duration_ms(result : SimulationResult) -> Int

#
simulation_scenario

fn simulation_scenario(name : String, operation : String, started_at_ms : Int, responses : Array[SimulatedResponse], repeat_last? : Bool) -> SimulationScenario

#
simulation_succeeded

fn simulation_succeeded(result : SimulationResult) -> Bool

#
simulation_summary

fn simulation_summary(results : Array[SimulationResult]) -> String

#
timeline_filter

fn timeline_filter(timeline : Array[TimelineEntry], label : String) -> Array[TimelineEntry]

#
token_bucket_acquire

fn token_bucket_acquire(bucket : TokenBucket, permits : Int, now_ms : Int) -> TokenBucketResult

#
token_bucket_config

fn token_bucket_config(capacity : Int, refill_tokens : Int, refill_period_ms : Int) -> TokenBucketConfig

#
token_bucket_reset

fn token_bucket_reset(bucket : TokenBucket, now_ms : Int) -> TokenBucket

#
token_bucket_with_tokens

fn token_bucket_with_tokens(config : TokenBucketConfig, tokens : Int, now_ms : Int) -> TokenBucket

#
total_retry_delay

fn total_retry_delay(policy : RetryPolicy) -> Int

#
trace_to_event_log

fn trace_to_event_log(trace : ExecutionTrace, operation : String, started_at_ms : Int) -> EventLog

#
validate_config

fn validate_config(config : ResilienceConfig) -> Result[ResilienceConfig, ConfigError]

#
virtual_clock

fn virtual_clock(now_ms : Int) -> VirtualClock