use serde::{Deserialize, Serialize};
pub mod cluster;
pub mod failover;
pub mod health_check;
pub mod load_balancing;
pub mod replication;
mod config;
pub use cluster::ClusterManager;
pub use config::HighAvailabilityConfig;
pub use failover::FailoverManager;
pub use health_check::HealthChecker;
pub use load_balancing::LoadBalancer;
pub use replication::ReplicationManager;
pub struct HighAvailabilityManager {
config: HighAvailabilityConfig,
cluster_manager: ClusterManager,
failover_manager: FailoverManager,
health_checker: HealthChecker,
replication_manager: ReplicationManager,
load_balancer: LoadBalancer,
}
impl HighAvailabilityManager {
pub fn new(config: HighAvailabilityConfig) -> Self {
let cluster_manager = ClusterManager::new(&config);
let failover_manager = FailoverManager::new(&config);
let health_checker = HealthChecker::new(&config);
let replication_manager = ReplicationManager::new(&config);
let load_balancer = LoadBalancer::new(&config);
Self {
config,
cluster_manager,
failover_manager,
health_checker,
replication_manager,
load_balancer,
}
}
pub async fn initialize(&mut self) -> Result<(), HaError> {
self.cluster_manager.initialize().await?;
self.health_checker.start_monitoring().await?;
self.replication_manager.initialize().await?;
self.load_balancer.initialize().await?;
self.failover_manager.initialize().await?;
Ok(())
}
pub async fn start(&mut self) -> Result<(), HaError> {
self.cluster_manager.join_cluster().await?;
self.health_checker.start_monitoring().await?;
self.replication_manager.start_replication().await?;
self.load_balancer.start().await?;
self.failover_manager.enable().await?;
Ok(())
}
pub async fn stop(&mut self) -> Result<(), HaError> {
self.failover_manager.disable().await?;
self.load_balancer.stop().await?;
self.replication_manager.stop_replication().await?;
self.health_checker.stop_monitoring().await?;
self.cluster_manager.leave_cluster().await?;
Ok(())
}
pub async fn get_cluster_status(&self) -> Result<ClusterStatus, HaError> {
self.cluster_manager.get_status().await
}
pub async fn get_health_status(&self) -> Result<HealthStatus, HaError> {
self.health_checker.get_status().await
}
pub async fn trigger_failover(&mut self) -> Result<(), HaError> {
self.failover_manager.trigger_manual_failover().await
}
pub async fn update_config(&mut self, config: HighAvailabilityConfig) -> Result<(), HaError> {
self.config = config.clone();
self.cluster_manager.update_config(&config).await?;
self.failover_manager.update_config(&config).await?;
self.health_checker.update_config(&config).await?;
self.replication_manager.update_config(&config).await?;
self.load_balancer.update_config(&config).await?;
Ok(())
}
}
#[derive(Debug, thiserror::Error)]
pub enum HaError {
#[error("Cluster operation failed: {0}")]
ClusterError(String),
#[error("Failover operation failed: {0}")]
FailoverError(String),
#[error("Health check failed: {0}")]
HealthCheckError(String),
#[error("Replication error: {0}")]
ReplicationError(String),
#[error("Load balancing error: {0}")]
LoadBalancerError(String),
#[error("Configuration error: {0}")]
ConfigError(String),
#[error("Network error: {0}")]
NetworkError(String),
#[error("I/O error: {0}")]
IoError(#[from] std::io::Error),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ClusterStatus {
Healthy,
Degraded {
active_nodes: usize,
total_nodes: usize,
details: String,
},
Failover {
primary_node: String,
failing_node: Option<String>,
failover_phase: FailoverPhase,
},
Initializing,
Down { reason: String },
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum FailoverPhase {
Detection,
Election,
Promotion,
Redirection,
Recovery,
Completed,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HealthStatus {
pub status: HealthState,
pub components: std::collections::HashMap<String, ComponentHealth>,
pub last_check: chrono::DateTime<chrono::Utc>,
pub message: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum HealthState {
Healthy,
Degraded,
Critical,
Unknown,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ComponentHealth {
pub name: String,
pub status: HealthState,
pub details: Option<String>,
pub last_check: chrono::DateTime<chrono::Utc>,
}