use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct HealthStatus {
pub is_healthy: bool,
pub circuit_breaker_open: bool,
pub warning_count: usize,
pub utilization: f64,
pub available_objects: usize,
pub active_objects: usize,
pub total_capacity: usize,
pub warnings: Vec<String>,
}
impl HealthStatus {
pub fn new(
available: usize,
active: usize,
capacity: usize,
circuit_breaker_open: bool,
) -> Self {
let utilization = if capacity > 0 {
active as f64 / capacity as f64
} else {
0.0
};
let mut warnings = Vec::new();
let mut is_healthy = true;
if utilization > 0.9 {
warnings.push(format!("High utilization: {:.1}%", utilization * 100.0));
is_healthy = false;
}
if available == 0 && capacity > 0 {
warnings.push("Pool is empty".to_string());
}
if circuit_breaker_open {
warnings.push("Circuit breaker is open".to_string());
is_healthy = false;
}
Self {
is_healthy,
circuit_breaker_open,
warning_count: warnings.len(),
utilization,
available_objects: available,
active_objects: active,
total_capacity: capacity,
warnings,
}
}
pub fn is_healthy(&self) -> bool {
self.is_healthy
}
}
#[allow(dead_code)]
pub(crate) struct HealthTracker {
pub total_retrieved: Arc<AtomicUsize>,
pub total_returned: Arc<AtomicUsize>,
pub pool_empty_count: Arc<AtomicUsize>,
pub validation_failures: Arc<AtomicUsize>,
pub is_healthy: Arc<AtomicBool>,
}
impl HealthTracker {
pub fn new() -> Self {
Self {
total_retrieved: Arc::new(AtomicUsize::new(0)),
total_returned: Arc::new(AtomicUsize::new(0)),
pool_empty_count: Arc::new(AtomicUsize::new(0)),
validation_failures: Arc::new(AtomicUsize::new(0)),
is_healthy: Arc::new(AtomicBool::new(true)),
}
}
pub fn increment_retrieved(&self) {
self.total_retrieved.fetch_add(1, Ordering::Relaxed);
}
pub fn increment_returned(&self) {
self.total_returned.fetch_add(1, Ordering::Relaxed);
}
pub fn increment_empty(&self) {
self.pool_empty_count.fetch_add(1, Ordering::Relaxed);
}
#[allow(dead_code)]
pub fn increment_validation_failure(&self) {
self.validation_failures.fetch_add(1, Ordering::Relaxed);
}
#[allow(dead_code)]
pub fn set_health(&self, healthy: bool) {
self.is_healthy.store(healthy, Ordering::Relaxed);
}
}
impl Default for HealthTracker {
fn default() -> Self {
Self::new()
}
}