Skip to main content

systemprompt_database/resilience/
config.rs

1//! Runtime configuration for the resilience primitives.
2//!
3//! These are the in-memory form used by [`super::guard::ResilienceGuard`].
4//! Callers that load configuration from disk (e.g. `systemprompt-models` config
5//! structs in milliseconds) translate into these `Duration`-typed structs at
6//! construction.
7//!
8//! Copyright (c) systemprompt.io — Business Source License 1.1.
9//! See <https://systemprompt.io> for licensing details.
10
11use std::time::Duration;
12
13#[derive(Debug, Clone, Copy)]
14pub struct RetryConfig {
15    pub max_attempts: u32,
16    pub base_delay: Duration,
17    pub max_delay: Duration,
18    pub jitter: bool,
19}
20
21impl Default for RetryConfig {
22    fn default() -> Self {
23        Self {
24            max_attempts: 3,
25            base_delay: Duration::from_millis(200),
26            max_delay: Duration::from_secs(10),
27            jitter: true,
28        }
29    }
30}
31
32#[derive(Debug, Clone, Copy)]
33pub struct BreakerConfig {
34    pub failure_threshold: u32,
35    pub open_cooldown: Duration,
36    pub half_open_max_probes: u32,
37}
38
39impl Default for BreakerConfig {
40    fn default() -> Self {
41        Self {
42            failure_threshold: 5,
43            open_cooldown: Duration::from_secs(30),
44            half_open_max_probes: 1,
45        }
46    }
47}
48
49#[derive(Debug, Clone, Copy)]
50pub struct BulkheadConfig {
51    pub max_concurrent: usize,
52}
53
54impl Default for BulkheadConfig {
55    fn default() -> Self {
56        Self { max_concurrent: 16 }
57    }
58}
59
60#[derive(Debug, Clone, Copy)]
61pub struct ResilienceConfig {
62    pub request_timeout: Duration,
63    pub stream_idle_timeout: Duration,
64    pub retry: RetryConfig,
65    pub breaker: BreakerConfig,
66    pub bulkhead: BulkheadConfig,
67}
68
69impl Default for ResilienceConfig {
70    fn default() -> Self {
71        Self {
72            request_timeout: Duration::from_secs(60),
73            stream_idle_timeout: Duration::from_secs(60),
74            retry: RetryConfig::default(),
75            breaker: BreakerConfig::default(),
76            bulkhead: BulkheadConfig::default(),
77        }
78    }
79}
80
81impl From<&systemprompt_models::services::ResilienceSettings> for ResilienceConfig {
82    fn from(settings: &systemprompt_models::services::ResilienceSettings) -> Self {
83        Self {
84            request_timeout: Duration::from_millis(settings.request_timeout_ms),
85            stream_idle_timeout: Duration::from_millis(settings.stream_idle_timeout_ms),
86            retry: RetryConfig {
87                max_attempts: settings.retry_attempts.max(1),
88                base_delay: Duration::from_millis(settings.retry_base_delay_ms),
89                max_delay: Duration::from_millis(settings.retry_max_delay_ms),
90                jitter: true,
91            },
92            breaker: BreakerConfig {
93                failure_threshold: settings.breaker_failure_threshold.max(1),
94                open_cooldown: Duration::from_millis(settings.breaker_open_cooldown_ms),
95                half_open_max_probes: settings.breaker_half_open_probes.max(1),
96            },
97            bulkhead: BulkheadConfig {
98                max_concurrent: settings.max_concurrent.max(1),
99            },
100        }
101    }
102}