#![allow(dead_code)]
use actr_protocol::{ActorResult, ActrError};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResourceQuota {
pub cpu_cores: f64,
pub memory_bytes: u64,
pub network_bandwidth_bps: u64,
pub disk_io_bps: u64,
}
impl Default for ResourceQuota {
fn default() -> Self {
Self {
cpu_cores: 1.0,
memory_bytes: 1024 * 1024 * 1024, network_bandwidth_bps: 100 * 1024 * 1024, disk_io_bps: 100 * 1024 * 1024, }
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ResourceUsage {
pub cpu_usage: f64,
pub memory_used_bytes: u64,
pub network_usage_bps: u64,
pub disk_io_bps: u64,
}
#[derive(Debug, Clone)]
pub struct ResourceConfig {
pub enable_limits: bool,
pub monitoring_interval_seconds: u64,
pub warning_threshold: f64,
pub limit_threshold: f64,
}
impl Default for ResourceConfig {
fn default() -> Self {
Self {
enable_limits: true,
monitoring_interval_seconds: 5,
warning_threshold: 0.8,
limit_threshold: 0.95,
}
}
}
pub struct ResourceManager {
config: ResourceConfig,
quota: ResourceQuota,
current_usage: ResourceUsage,
}
impl ResourceManager {
pub fn new(config: ResourceConfig, quota: ResourceQuota) -> Self {
Self {
config,
quota,
current_usage: ResourceUsage::default(),
}
}
pub fn check_resource_availability(&self, required: &ResourceUsage) -> ActorResult<bool> {
if !self.config.enable_limits {
return Ok(true);
}
let cpu_available =
self.quota.cpu_cores - (self.current_usage.cpu_usage * self.quota.cpu_cores);
if required.cpu_usage * self.quota.cpu_cores > cpu_available {
return Ok(false);
}
let memory_available = self.quota.memory_bytes - self.current_usage.memory_used_bytes;
if required.memory_used_bytes > memory_available {
return Ok(false);
}
Ok(true)
}
pub fn allocate_resources(&mut self, usage: &ResourceUsage) -> ActorResult<()> {
if !self.check_resource_availability(usage)? {
return Err(ActrError::Unavailable(
"Insufficient resources available".to_string(),
));
}
self.current_usage.cpu_usage += usage.cpu_usage;
self.current_usage.memory_used_bytes += usage.memory_used_bytes;
self.current_usage.network_usage_bps += usage.network_usage_bps;
self.current_usage.disk_io_bps += usage.disk_io_bps;
Ok(())
}
pub fn release_resources(&mut self, usage: &ResourceUsage) -> ActorResult<()> {
self.current_usage.cpu_usage = (self.current_usage.cpu_usage - usage.cpu_usage).max(0.0);
self.current_usage.memory_used_bytes = self
.current_usage
.memory_used_bytes
.saturating_sub(usage.memory_used_bytes);
self.current_usage.network_usage_bps = self
.current_usage
.network_usage_bps
.saturating_sub(usage.network_usage_bps);
self.current_usage.disk_io_bps = self
.current_usage
.disk_io_bps
.saturating_sub(usage.disk_io_bps);
Ok(())
}
pub fn get_usage(&self) -> &ResourceUsage {
&self.current_usage
}
pub fn get_quota(&self) -> &ResourceQuota {
&self.quota
}
pub fn calculate_usage_ratio(&self) -> ResourceUsageRatio {
ResourceUsageRatio {
cpu_ratio: self.current_usage.cpu_usage,
memory_ratio: self.current_usage.memory_used_bytes as f64
/ self.quota.memory_bytes as f64,
network_ratio: self.current_usage.network_usage_bps as f64
/ self.quota.network_bandwidth_bps as f64,
disk_ratio: self.current_usage.disk_io_bps as f64 / self.quota.disk_io_bps as f64,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResourceUsageRatio {
pub cpu_ratio: f64,
pub memory_ratio: f64,
pub network_ratio: f64,
pub disk_ratio: f64,
}