Skip to main content

arete_server/
config.rs

1use std::net::SocketAddr;
2use std::time::Duration;
3
4pub use crate::health::HealthConfig;
5pub use crate::http_health::HttpHealthConfig;
6pub use crate::http_server::HttpServerConfig;
7
8/// Configuration for gRPC stream reconnection with exponential backoff
9#[derive(Clone, Debug)]
10pub struct ReconnectionConfig {
11    /// Initial delay before first reconnection attempt
12    pub initial_delay: Duration,
13    /// Maximum delay between reconnection attempts
14    pub max_delay: Duration,
15    /// Maximum number of reconnection attempts (None = infinite)
16    pub max_attempts: Option<u32>,
17    /// Multiplier for exponential backoff (typically 2.0)
18    pub backoff_multiplier: f64,
19    /// HTTP/2 keep-alive interval to prevent silent disconnects
20    pub http2_keep_alive_interval: Option<Duration>,
21}
22
23impl Default for ReconnectionConfig {
24    fn default() -> Self {
25        Self {
26            initial_delay: Duration::from_millis(100),
27            max_delay: Duration::from_secs(60),
28            max_attempts: None, // Infinite retries by default
29            backoff_multiplier: 2.0,
30            http2_keep_alive_interval: Some(Duration::from_secs(30)),
31        }
32    }
33}
34
35impl ReconnectionConfig {
36    pub fn new() -> Self {
37        Self::default()
38    }
39
40    pub fn with_initial_delay(mut self, delay: Duration) -> Self {
41        self.initial_delay = delay;
42        self
43    }
44
45    pub fn with_max_delay(mut self, delay: Duration) -> Self {
46        self.max_delay = delay;
47        self
48    }
49
50    pub fn with_max_attempts(mut self, attempts: u32) -> Self {
51        self.max_attempts = Some(attempts);
52        self
53    }
54
55    pub fn with_backoff_multiplier(mut self, multiplier: f64) -> Self {
56        self.backoff_multiplier = multiplier;
57        self
58    }
59
60    pub fn with_http2_keep_alive_interval(mut self, interval: Duration) -> Self {
61        self.http2_keep_alive_interval = Some(interval);
62        self
63    }
64
65    /// Calculate the next backoff duration given the current one
66    pub fn next_backoff(&self, current: Duration) -> Duration {
67        let next_secs = current.as_secs_f64() * self.backoff_multiplier;
68        let capped_secs = next_secs.min(self.max_delay.as_secs_f64());
69        Duration::from_secs_f64(capped_secs)
70    }
71}
72
73/// WebSocket server configuration
74#[derive(Clone, Debug)]
75pub struct WebSocketConfig {
76    pub bind_address: SocketAddr,
77}
78
79impl Default for WebSocketConfig {
80    fn default() -> Self {
81        Self {
82            bind_address: "[::]:8877".parse().expect("valid socket address"),
83        }
84    }
85}
86
87impl WebSocketConfig {
88    pub fn new(bind_address: impl Into<SocketAddr>) -> Self {
89        Self {
90            bind_address: bind_address.into(),
91        }
92    }
93}
94
95/// Yellowstone gRPC configuration
96#[derive(Clone, Debug)]
97pub struct YellowstoneConfig {
98    pub endpoint: String,
99    pub x_token: Option<String>,
100}
101
102impl YellowstoneConfig {
103    pub fn new(endpoint: impl Into<String>) -> Self {
104        Self {
105            endpoint: endpoint.into(),
106            x_token: None,
107        }
108    }
109
110    pub fn with_token(mut self, token: impl Into<String>) -> Self {
111        self.x_token = Some(token.into());
112        self
113    }
114}
115
116/// Main server configuration
117#[derive(Clone, Debug, Default)]
118pub struct ServerConfig {
119    pub websocket: Option<WebSocketConfig>,
120    pub yellowstone: Option<YellowstoneConfig>,
121    pub health: Option<HealthConfig>,
122    pub http_health: Option<HttpHealthConfig>,
123    pub reconnection: Option<ReconnectionConfig>,
124}
125
126impl ServerConfig {
127    pub fn new() -> Self {
128        Self::default()
129    }
130
131    pub fn with_websocket(mut self, config: WebSocketConfig) -> Self {
132        self.websocket = Some(config);
133        self
134    }
135
136    pub fn with_yellowstone(mut self, config: YellowstoneConfig) -> Self {
137        self.yellowstone = Some(config);
138        self
139    }
140
141    pub fn with_health(mut self, config: HealthConfig) -> Self {
142        self.health = Some(config);
143        self
144    }
145
146    pub fn with_http_health(mut self, config: HttpHealthConfig) -> Self {
147        self.http_health = Some(config);
148        self
149    }
150
151    pub fn with_reconnection(mut self, config: ReconnectionConfig) -> Self {
152        self.reconnection = Some(config);
153        self
154    }
155}