anya_core/infrastructure/high_availability/
config.rs

1use serde::{Deserialize, Serialize};
2use std::time::Duration;
3
4/// Configuration for high availability system
5/// [AIR-3][AIS-3][PFM-3][SCL-3][RES-3]
6#[derive(Debug, Clone, Serialize, Deserialize, Default)]
7pub struct HighAvailabilityConfig {
8    /// General high availability settings
9    pub general: GeneralConfig,
10
11    /// Cluster management configuration
12    pub cluster: ClusterConfig,
13
14    /// Health check configuration
15    pub health_check: HealthCheckConfig,
16
17    /// Failover configuration
18    pub failover: FailoverConfig,
19
20    /// Replication configuration
21    pub replication: ReplicationConfig,
22
23    /// Load balancing configuration
24    pub load_balancing: LoadBalancingConfig,
25
26    /// Disaster recovery configuration
27    pub disaster_recovery: DisasterRecoveryConfig,
28}
29
30impl HighAvailabilityConfig {
31    /// Creates a new configuration for development environment
32    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    /// Creates a new configuration for production environment
51    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/// General high availability settings
102#[derive(Debug, Clone, Serialize, Deserialize)]
103pub struct GeneralConfig {
104    /// Whether high availability is enabled
105    pub enabled: bool,
106
107    /// Environment type
108    pub environment: Environment,
109
110    /// Log level
111    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/// Environment types
125#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
126pub enum Environment {
127    Development,
128    Staging,
129    Production,
130}
131
132/// Log levels
133#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
134pub enum LogLevel {
135    Trace,
136    Debug,
137    Info,
138    Warn,
139    Error,
140}
141
142/// Cluster configuration
143#[derive(Debug, Clone, Serialize, Deserialize)]
144pub struct ClusterConfig {
145    /// Number of nodes in the cluster
146    pub node_count: usize,
147
148    /// Cluster name
149    pub cluster_name: String,
150
151    /// Method used for node discovery
152    pub discovery_method: DiscoveryMethod,
153
154    /// List of static nodes (for static discovery)
155    #[serde(default)]
156    pub static_nodes: Vec<String>,
157
158    /// DNS address for DNS discovery
159    pub dns_discovery_url: Option<String>,
160
161    /// Kubernetes service name for K8s discovery
162    pub k8s_service_name: Option<String>,
163
164    /// Heartbeat interval
165    #[serde(with = "humantime_serde")]
166    pub heartbeat_interval: Duration,
167
168    /// Node timeout
169    #[serde(with = "humantime_serde")]
170    pub node_timeout: Duration,
171
172    /// Gossip interval
173    #[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/// Methods for node discovery
194#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
195pub enum DiscoveryMethod {
196    Static,
197    Dns,
198    Kubernetes,
199    Consul,
200    Etcd,
201}
202
203/// Health check configuration
204#[derive(Debug, Clone, Serialize, Deserialize)]
205pub struct HealthCheckConfig {
206    /// Whether health checking is enabled
207    pub enabled: bool,
208
209    /// Health check interval
210    #[serde(with = "humantime_serde")]
211    pub check_interval: Duration,
212
213    /// Number of failed checks to trigger warning
214    pub warning_threshold: u32,
215
216    /// Number of failed checks to trigger critical
217    pub critical_threshold: u32,
218
219    /// Timeout for health checks
220    #[serde(with = "humantime_serde")]
221    pub check_timeout: Duration,
222
223    /// Components to check
224    #[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/// Failover configuration
246#[derive(Debug, Clone, Serialize, Deserialize)]
247pub struct FailoverConfig {
248    /// Whether failover is enabled
249    pub enabled: bool,
250
251    /// Whether automatic failover is enabled
252    pub auto_failover: bool,
253
254    /// Timeout before triggering failover
255    #[serde(with = "humantime_serde")]
256    pub failover_timeout: Duration,
257
258    /// Minimum number of nodes required for failover
259    pub min_nodes_for_failover: usize,
260
261    /// Maximum number of automatic failovers per period
262    pub max_auto_failovers: Option<u32>,
263
264    /// Period for auto failover limits
265    #[serde(with = "humantime_serde")]
266    pub auto_failover_period: Duration,
267
268    /// Fencing enabled
269    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/// Replication configuration
287#[derive(Debug, Clone, Serialize, Deserialize)]
288pub struct ReplicationConfig {
289    /// Replication mode
290    pub mode: ReplicationMode,
291
292    /// Timeout for synchronous replication
293    #[serde(with = "humantime_serde")]
294    pub sync_timeout: Duration,
295
296    /// Maximum lag for semi-sync replication
297    #[serde(with = "humantime_serde")]
298    pub max_lag: Duration,
299
300    /// Number of acknowledgments required (for semi-sync)
301    pub ack_count: Option<usize>,
302
303    /// Compression enabled
304    pub compression_enabled: bool,
305
306    /// Encryption enabled
307    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/// Replication modes
324#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
325pub enum ReplicationMode {
326    Synchronous,
327    SemiSynchronous,
328    Asynchronous,
329}
330
331/// Load balancing configuration
332#[derive(Debug, Clone, Serialize, Deserialize)]
333pub struct LoadBalancingConfig {
334    /// Load balancing algorithm
335    pub algorithm: LoadBalancingAlgorithm,
336
337    /// Whether to check health for load balancing
338    pub health_check_enabled: bool,
339
340    /// Whether to use sticky sessions
341    pub sticky_sessions: bool,
342
343    /// Whether to enable auto scaling
344    pub auto_scaling: bool,
345
346    /// Minimum number of nodes
347    pub min_nodes: Option<usize>,
348
349    /// Maximum number of nodes
350    pub max_nodes: Option<usize>,
351
352    /// Scale up threshold (load percentage)
353    pub scale_up_threshold: Option<f32>,
354
355    /// Scale down threshold (load percentage)
356    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/// Load balancing algorithms
375#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
376pub enum LoadBalancingAlgorithm {
377    RoundRobin,
378    LeastConnections,
379    LeastResponseTime,
380    WeightedRoundRobin,
381    ResourceBased,
382}
383
384/// Disaster recovery configuration
385#[derive(Debug, Clone, Serialize, Deserialize)]
386pub struct DisasterRecoveryConfig {
387    /// Backup interval
388    #[serde(with = "humantime_serde")]
389    pub backup_interval: Duration,
390
391    /// Backup retention days
392    pub backup_retention: u32,
393
394    /// Whether auto restore is enabled
395    pub auto_restore: bool,
396
397    /// Remote backup location
398    pub remote_backup_location: Option<String>,
399
400    /// Encryption key for backups
401    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), // 1 hour
408            backup_retention: 30,                       // 30 days
409            auto_restore: false,
410            remote_backup_location: None,
411            backup_encryption_key: None,
412        }
413    }
414}