Skip to main content

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}