A pure MoonBit resilience toolkit for retry, circuit breaking, rate limiting, bulkhead isolation, telemetry, and deterministic simulation.
moon check
moon test
moon run cmd/mainlet 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")
}
},
)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.
├── 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 analyzepub(all) struct BatchResult {
items : Array[BatchItemResult]
final_chain : PolicyChain
stopped_early : Bool
} derive(Debug)pub(all) enum BreakerDecision {
BreakerAllowed(CircuitBreaker, Bool)
BreakerRejected(CircuitBreaker, Int, String)
} derive(Eq, Debug)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)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)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)pub(all) enum EventKind {
ExecutionStarted
ExecutionSucceeded
ExecutionFailed
RetryScheduledEvent
CircuitOpenedEvent
CircuitHalfOpenedEvent
CircuitClosedEvent
RateLimitGrantedEvent
RateLimitRejectedEvent
BulkheadEnteredEvent
BulkheadQueuedEvent
BulkheadRejectedEvent
BulkheadReleasedEvent
} derive(Eq, Debug)pub(all) struct EventLog {
events : Array[ResilienceEvent]
max_events : Int
dropped_events : Int
} derive(Eq, Debug)pub(all) struct ExecutionResult[T] {
outcome : Result[T, ExecuteError]
chain : PolicyChain
attempts : Int
started_at_ms : Int
finished_at_ms : Int
trace : ExecutionTrace
}pub(all) struct FixedWindowLimiter {
config : FixedWindowConfig
window_started_ms : Int
used : Int
total_granted : Int
total_rejected : Int
} derive(Eq, Debug)pub(all) struct FixedWindowResult {
limiter : FixedWindowLimiter
decision : RateLimitDecision
} derive(Eq, Debug)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)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)pub(all) struct Metrics {
counters : Array[MetricCounter]
latency_count : Int
latency_total_ms : Int
latency_max_ms : Int
} derive(Eq, Debug)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)pub(all) struct NamedPolicy {
name : String
chain : PolicyChain
description : String
} derive(Eq, Debug)pub(all) struct PolicyChain {
retry : RetryPolicy
breaker : CircuitBreaker
rate_limit : RateLimitPolicy
bulkhead : Bulkhead
} derive(Eq, Debug)pub(all) struct PolicyRegistry {
policies : Array[NamedPolicy]
default_name : String?
} derive(Eq, Debug)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)pub(all) enum RateLimitPolicy {
TokenBucketPolicy(TokenBucket)
FixedWindowPolicy(FixedWindowLimiter)
} derive(Eq, Debug)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)pub(all) struct RetryPolicy {
max_attempts : Int
max_elapsed_ms : Int
backoff : BackoffStrategy
retryable_codes : Array[String]
} derive(Eq, Debug)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)pub(all) struct SimulationScenario {
name : String
operation : String
started_at_ms : Int
responses : Array[SimulatedResponse]
repeat_last : Bool
} derive(Eq, Debug)pub(all) struct TokenBucket {
config : TokenBucketConfig
available_tokens : Int
last_refill_ms : Int
total_granted : Int
total_rejected : Int
} derive(Eq, Debug)pub(all) struct TokenBucketResult {
bucket : TokenBucket
decision : RateLimitDecision
} derive(Eq, Debug)fn circuit_breaker_config(failure_threshold : Int, success_threshold : Int, open_window_ms : Int, half_open_max_calls : Int) -> CircuitBreakerConfigfn config_to_policy_chain(config : ResilienceConfig, now_ms : Int) -> Result[PolicyChain, ConfigError]fn[T] execute_with(chain : PolicyChain, context : ExecutionContext, action : (Int, Int) -> ActionOutcome[T]) -> ExecutionResult[T]fn export_latency_prometheus(snapshot : LatencySnapshot, prefix? : String, labels? : Array[MetricLabel]) -> Result[String, String]fn export_prometheus(snapshot : MetricsSnapshot, prefix? : String, labels? : Array[MetricLabel]) -> Result[String, String]fn fixed_window_acquire(limiter : FixedWindowLimiter, permits : Int, now_ms : Int) -> FixedWindowResultfn latency_merge(left : LatencyHistogram, right : LatencyHistogram) -> Result[LatencyHistogram, String]fn policy_chain(retry : RetryPolicy, breaker : CircuitBreaker, rate_limit : RateLimitPolicy, bulkhead : Bulkhead) -> PolicyChainfn registry_add(registry : PolicyRegistry, name : String, chain : PolicyChain, description? : String) -> Result[PolicyRegistry, RegistryError]fn registry_remove(registry : PolicyRegistry, name : String) -> Result[PolicyRegistry, RegistryError]fn registry_replace(registry : PolicyRegistry, name : String, chain : PolicyChain, description? : String) -> Result[PolicyRegistry, RegistryError]fn registry_set_default(registry : PolicyRegistry, name : String) -> Result[PolicyRegistry, RegistryError]fn resilience_event(kind : EventKind, at_ms : Int, operation : String, detail : String, value : Int) -> ResilienceEventfn retry_policy(max_attempts : Int, max_elapsed_ms : Int, backoff : BackoffStrategy, retryable_codes : Array[String]) -> RetryPolicyfn retry_snapshot(policy : RetryPolicy, failure : AttemptFailure, attempt : Int, elapsed_ms : Int) -> RetrySnapshotfn run_batch(chain : PolicyChain, requests : Array[BatchRequest], stop_on_failure? : Bool) -> BatchResultfn run_scenarios(chain : PolicyChain, scenarios : Array[SimulationScenario]) -> Array[SimulationResult]fn should_retry(policy : RetryPolicy, failure : AttemptFailure, attempt : Int, elapsed_ms : Int) -> Boolfn simulated_failure(code : String, message : String, retryable : Bool, latency_ms : Int) -> SimulatedResponsefn simulation_scenario(name : String, operation : String, started_at_ms : Int, responses : Array[SimulatedResponse], repeat_last? : Bool) -> SimulationScenariofn token_bucket_config(capacity : Int, refill_tokens : Int, refill_period_ms : Int) -> TokenBucketConfigA pure MoonBit resilience toolkit for retry, circuit breaking, rate limiting, bulkhead isolation, telemetry, and deterministic simulation.