1use serde::{Deserialize, Serialize};
2use std::time::Duration;
3
4#[derive(Debug, Clone, Serialize, Deserialize, Default)]
7pub struct HighAvailabilityConfig {
8 pub general: GeneralConfig,
10
11 pub cluster: ClusterConfig,
13
14 pub health_check: HealthCheckConfig,
16
17 pub failover: FailoverConfig,
19
20 pub replication: ReplicationConfig,
22
23 pub load_balancing: LoadBalancingConfig,
25
26 pub disaster_recovery: DisasterRecoveryConfig,
28}
29
30impl HighAvailabilityConfig {
31 pub fn development() -> Self {
33 Self {
34 general: GeneralConfig {
35 enabled: true,
36 environment: Environment::Development,
37 log_level: LogLevel::Debug,
38 },
39 cluster: ClusterConfig {
40 node_count: 2,
41 cluster_name: "anya-dev-cluster".to_string(),
42 discovery_method: DiscoveryMethod::Static,
43 static_nodes: vec!["localhost:5001".to_string(), "localhost:5002".to_string()],
44 ..Default::default()
45 },
46 ..Default::default()
47 }
48 }
49
50 pub fn production() -> Self {
52 Self {
53 general: GeneralConfig {
54 enabled: true,
55 environment: Environment::Production,
56 log_level: LogLevel::Info,
57 },
58 cluster: ClusterConfig {
59 node_count: 3,
60 cluster_name: "anya-prod-cluster".to_string(),
61 discovery_method: DiscoveryMethod::Dns,
62 dns_discovery_url: Some("anya-cluster.example.com".to_string()),
63 heartbeat_interval: Duration::from_secs(5),
64 ..Default::default()
65 },
66 health_check: HealthCheckConfig {
67 enabled: true,
68 check_interval: Duration::from_secs(10),
69 critical_threshold: 3,
70 warning_threshold: 2,
71 ..Default::default()
72 },
73 failover: FailoverConfig {
74 enabled: true,
75 auto_failover: true,
76 failover_timeout: Duration::from_secs(30),
77 min_nodes_for_failover: 2,
78 ..Default::default()
79 },
80 replication: ReplicationConfig {
81 mode: ReplicationMode::Synchronous,
82 sync_timeout: Duration::from_secs(10),
83 ..Default::default()
84 },
85 load_balancing: LoadBalancingConfig {
86 algorithm: LoadBalancingAlgorithm::RoundRobin,
87 health_check_enabled: true,
88 auto_scaling: true,
89 ..Default::default()
90 },
91 disaster_recovery: DisasterRecoveryConfig {
92 backup_interval: Duration::from_secs(3600),
93 backup_retention: 7,
94 auto_restore: true,
95 ..Default::default()
96 },
97 }
98 }
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize)]
103pub struct GeneralConfig {
104 pub enabled: bool,
106
107 pub environment: Environment,
109
110 pub log_level: LogLevel,
112}
113
114impl Default for GeneralConfig {
115 fn default() -> Self {
116 Self {
117 enabled: true,
118 environment: Environment::Development,
119 log_level: LogLevel::Info,
120 }
121 }
122}
123
124#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
126pub enum Environment {
127 Development,
128 Staging,
129 Production,
130}
131
132#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
134pub enum LogLevel {
135 Trace,
136 Debug,
137 Info,
138 Warn,
139 Error,
140}
141
142#[derive(Debug, Clone, Serialize, Deserialize)]
144pub struct ClusterConfig {
145 pub node_count: usize,
147
148 pub cluster_name: String,
150
151 pub discovery_method: DiscoveryMethod,
153
154 #[serde(default)]
156 pub static_nodes: Vec<String>,
157
158 pub dns_discovery_url: Option<String>,
160
161 pub k8s_service_name: Option<String>,
163
164 #[serde(with = "humantime_serde")]
166 pub heartbeat_interval: Duration,
167
168 #[serde(with = "humantime_serde")]
170 pub node_timeout: Duration,
171
172 #[serde(with = "humantime_serde")]
174 pub gossip_interval: Duration,
175}
176
177impl Default for ClusterConfig {
178 fn default() -> Self {
179 Self {
180 node_count: 1,
181 cluster_name: "anya-cluster".to_string(),
182 discovery_method: DiscoveryMethod::Static,
183 static_nodes: vec!["localhost:5001".to_string()],
184 dns_discovery_url: None,
185 k8s_service_name: None,
186 heartbeat_interval: Duration::from_secs(10),
187 node_timeout: Duration::from_secs(30),
188 gossip_interval: Duration::from_secs(1),
189 }
190 }
191}
192
193#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
195pub enum DiscoveryMethod {
196 Static,
197 Dns,
198 Kubernetes,
199 Consul,
200 Etcd,
201}
202
203#[derive(Debug, Clone, Serialize, Deserialize)]
205pub struct HealthCheckConfig {
206 pub enabled: bool,
208
209 #[serde(with = "humantime_serde")]
211 pub check_interval: Duration,
212
213 pub warning_threshold: u32,
215
216 pub critical_threshold: u32,
218
219 #[serde(with = "humantime_serde")]
221 pub check_timeout: Duration,
222
223 #[serde(default)]
225 pub components: Vec<String>,
226}
227
228impl Default for HealthCheckConfig {
229 fn default() -> Self {
230 Self {
231 enabled: true,
232 check_interval: Duration::from_secs(30),
233 warning_threshold: 2,
234 critical_threshold: 3,
235 check_timeout: Duration::from_secs(5),
236 components: vec![
237 "cluster".to_string(),
238 "storage".to_string(),
239 "network".to_string(),
240 ],
241 }
242 }
243}
244
245#[derive(Debug, Clone, Serialize, Deserialize)]
247pub struct FailoverConfig {
248 pub enabled: bool,
250
251 pub auto_failover: bool,
253
254 #[serde(with = "humantime_serde")]
256 pub failover_timeout: Duration,
257
258 pub min_nodes_for_failover: usize,
260
261 pub max_auto_failovers: Option<u32>,
263
264 #[serde(with = "humantime_serde")]
266 pub auto_failover_period: Duration,
267
268 pub fencing_enabled: bool,
270}
271
272impl Default for FailoverConfig {
273 fn default() -> Self {
274 Self {
275 enabled: true,
276 auto_failover: true,
277 failover_timeout: Duration::from_secs(60),
278 min_nodes_for_failover: 2,
279 max_auto_failovers: Some(3),
280 auto_failover_period: Duration::from_secs(3600),
281 fencing_enabled: true,
282 }
283 }
284}
285
286#[derive(Debug, Clone, Serialize, Deserialize)]
288pub struct ReplicationConfig {
289 pub mode: ReplicationMode,
291
292 #[serde(with = "humantime_serde")]
294 pub sync_timeout: Duration,
295
296 #[serde(with = "humantime_serde")]
298 pub max_lag: Duration,
299
300 pub ack_count: Option<usize>,
302
303 pub compression_enabled: bool,
305
306 pub encryption_enabled: bool,
308}
309
310impl Default for ReplicationConfig {
311 fn default() -> Self {
312 Self {
313 mode: ReplicationMode::SemiSynchronous,
314 sync_timeout: Duration::from_secs(5),
315 max_lag: Duration::from_millis(500),
316 ack_count: None,
317 compression_enabled: true,
318 encryption_enabled: true,
319 }
320 }
321}
322
323#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
325pub enum ReplicationMode {
326 Synchronous,
327 SemiSynchronous,
328 Asynchronous,
329}
330
331#[derive(Debug, Clone, Serialize, Deserialize)]
333pub struct LoadBalancingConfig {
334 pub algorithm: LoadBalancingAlgorithm,
336
337 pub health_check_enabled: bool,
339
340 pub sticky_sessions: bool,
342
343 pub auto_scaling: bool,
345
346 pub min_nodes: Option<usize>,
348
349 pub max_nodes: Option<usize>,
351
352 pub scale_up_threshold: Option<f32>,
354
355 pub scale_down_threshold: Option<f32>,
357}
358
359impl Default for LoadBalancingConfig {
360 fn default() -> Self {
361 Self {
362 algorithm: LoadBalancingAlgorithm::LeastConnections,
363 health_check_enabled: true,
364 sticky_sessions: false,
365 auto_scaling: false,
366 min_nodes: Some(1),
367 max_nodes: Some(10),
368 scale_up_threshold: Some(0.75),
369 scale_down_threshold: Some(0.25),
370 }
371 }
372}
373
374#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
376pub enum LoadBalancingAlgorithm {
377 RoundRobin,
378 LeastConnections,
379 LeastResponseTime,
380 WeightedRoundRobin,
381 ResourceBased,
382}
383
384#[derive(Debug, Clone, Serialize, Deserialize)]
386pub struct DisasterRecoveryConfig {
387 #[serde(with = "humantime_serde")]
389 pub backup_interval: Duration,
390
391 pub backup_retention: u32,
393
394 pub auto_restore: bool,
396
397 pub remote_backup_location: Option<String>,
399
400 pub backup_encryption_key: Option<String>,
402}
403
404impl Default for DisasterRecoveryConfig {
405 fn default() -> Self {
406 Self {
407 backup_interval: Duration::from_secs(3600), backup_retention: 30, auto_restore: false,
410 remote_backup_location: None,
411 backup_encryption_key: None,
412 }
413 }
414}