cloud-disk-sync 0.1.0

a cloud disk sync tool
Documentation
use super::traits::HealthChecker;
use crate::error::{ProviderError, Result, SyncError};
use async_trait::async_trait;
use std::collections::HashMap;
use std::time::{Duration, Instant};

pub struct HealthCheckerImpl {
    providers: HashMap<String, Box<dyn crate::providers::StorageProvider>>,
}

impl HealthCheckerImpl {
    pub fn new(providers: HashMap<String, Box<dyn crate::providers::StorageProvider>>) -> Self {
        Self { providers }
    }
}

#[derive(Debug, Clone, Default)]
struct TempStorageHealth {}

#[async_trait]
impl HealthChecker for HealthCheckerImpl {
    async fn check_provider_health(&self, provider_id: &str) -> Result<HealthStatus> {
        let provider = self
            .providers
            .get(provider_id)
            .ok_or_else(|| SyncError::Provider(ProviderError::NotFound(provider_id.into())))?;

        let start_time = Instant::now();

        // 执行简单的健康检查(如列出根目录)
        match provider.list("/").await {
            Ok(_) => {
                let response_time = start_time.elapsed();

                Ok(HealthStatus::Healthy {
                    provider_id: provider_id.into(),
                    response_time,
                    last_check: chrono::Utc::now(),
                })
            }
            Err(e) => Ok(HealthStatus::Unhealthy {
                provider_id: provider_id.into(),
                error: e.to_string(),
                last_check: chrono::Utc::now(),
            }),
        }
    }

    async fn check_storage_health(&self) -> Result<StorageHealth> {
        let mut health = StorageHealth {
            local_storage: LocalStorageHealth::default(),
            temp_storage: TempStorageHealth::default(),
            database_health: DatabaseHealth::default(),
            overall: HealthStatus::Healthy {
                provider_id: "system".into(),
                response_time: Duration::from_secs(0),
                last_check: chrono::Utc::now(),
            },
        };

        // 检查本地存储空间
        if let Some(data_dir) = dirs::data_dir() {
            let avail = fs2::available_space(&data_dir).unwrap_or(0);
            let total = fs2::total_space(&data_dir).unwrap_or(0);
            health.local_storage.available_space = avail;
            health.local_storage.total_space = total;
            let used = total.saturating_sub(avail);
            health.local_storage.usage_percentage = if total > 0 {
                (used as f64 / total as f64) * 100.0
            } else {
                0.0
            };

            if health.local_storage.usage_percentage > 90.0 {
                health.overall = HealthStatus::Degraded {
                    provider_id: "local_storage".into(),
                    warning: "Local storage usage is high".into(),
                    last_check: chrono::Utc::now(),
                };
            }
        }

        Ok(health)
    }

    async fn check_connectivity(&self) -> Result<ConnectivityStatus> {
        let mut status = ConnectivityStatus {
            internet: false,
            dns_resolution: false,
            proxy_configured: false,
            connectivity_tests: Vec::new(),
        };

        // 测试互联网连接
        let internet_test = ConnectivityTest {
            name: "Internet".into(),
            target: "8.8.8.8:53".into(),
            protocol: Protocol::UDP,
            timeout: Duration::from_secs(3),
            success: false,
            latency: None,
        };

        // 这里实现实际的连接测试
        // 简化处理

        Ok(status)
    }
}

#[derive(Debug, Clone)]
pub enum HealthStatus {
    Healthy {
        provider_id: String,
        response_time: Duration,
        last_check: chrono::DateTime<chrono::Utc>,
    },
    Degraded {
        provider_id: String,
        warning: String,
        last_check: chrono::DateTime<chrono::Utc>,
    },
    Unhealthy {
        provider_id: String,
        error: String,
        last_check: chrono::DateTime<chrono::Utc>,
    },
}

#[derive(Debug, Clone)]
pub struct StorageHealth {
    pub local_storage: LocalStorageHealth,
    pub temp_storage: TempStorageHealth,
    pub database_health: DatabaseHealth,
    pub overall: HealthStatus,
}

#[derive(Debug, Clone, Default)]
pub struct LocalStorageHealth {
    pub available_space: u64,
    pub total_space: u64,
    pub usage_percentage: f64,
    pub is_readable: bool,
    pub is_writable: bool,
}

#[derive(Debug, Clone, Default)]
pub struct DatabaseHealth {}

#[derive(Debug, Clone)]
pub struct ConnectivityStatus {
    pub internet: bool,
    pub dns_resolution: bool,
    pub proxy_configured: bool,
    pub connectivity_tests: Vec<ConnectivityTest>,
}

#[derive(Debug, Clone)]
pub struct ConnectivityTest {
    pub name: String,
    pub target: String,
    pub protocol: Protocol,
    pub timeout: Duration,
    pub success: bool,
    pub latency: Option<Duration>,
}

#[derive(Debug, Clone)]
pub enum Protocol {
    TCP,
    UDP,
    HTTP,
    HTTPS,
}