convergio_types/resilience.rs
1//! Resilience primitives — retry and circuit breaker configuration.
2//!
3//! These are pure config/state types. Runtime implementations
4//! (async retry, breaker state machine) live in the crates that use them.
5
6use std::time::Duration;
7
8/// Configuration for retry with exponential backoff.
9#[derive(Debug, Clone)]
10pub struct RetryConfig {
11 /// Additional attempts after the initial one (0 = no retry).
12 pub max_retries: u32,
13 /// Delay before the first retry.
14 pub initial_delay: Duration,
15 /// Maximum delay between retries (caps exponential growth).
16 pub max_delay: Duration,
17 /// Multiplier applied after each failure (e.g. 2.0 = double).
18 pub backoff_factor: f64,
19 /// When true, adds ±25% random jitter to each delay.
20 pub jitter: bool,
21}
22
23impl Default for RetryConfig {
24 fn default() -> Self {
25 Self {
26 max_retries: 3,
27 initial_delay: Duration::from_millis(100),
28 max_delay: Duration::from_secs(10),
29 backoff_factor: 2.0,
30 jitter: true,
31 }
32 }
33}
34
35/// Circuit breaker states.
36#[derive(Debug, Clone, Copy, PartialEq, Eq)]
37pub enum CircuitState {
38 /// Normal operation — requests pass through.
39 Closed,
40 /// Too many failures — requests are rejected immediately.
41 Open,
42 /// Testing recovery — limited requests allowed.
43 HalfOpen,
44}
45
46/// Configuration for a circuit breaker.
47#[derive(Debug, Clone)]
48pub struct CircuitBreakerConfig {
49 /// Number of consecutive failures before opening.
50 pub failure_threshold: u32,
51 /// How long the circuit stays open before transitioning to half-open.
52 pub reset_timeout: Duration,
53 /// Number of successful requests in half-open needed to close.
54 pub success_threshold: u32,
55}
56
57impl Default for CircuitBreakerConfig {
58 fn default() -> Self {
59 Self {
60 failure_threshold: 5,
61 reset_timeout: Duration::from_secs(30),
62 success_threshold: 2,
63 }
64 }
65}