Skip to main content

symbi_runtime/types/
resource.rs

1//! Resource management types and data structures
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use std::time::Duration;
6
7use super::AgentId;
8
9/// Resource limits for an agent
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct ResourceLimits {
12    pub memory_mb: usize,
13    pub cpu_cores: f32,
14    pub disk_io_mbps: usize,
15    pub network_io_mbps: usize,
16    pub execution_timeout: Duration,
17    pub idle_timeout: Duration,
18}
19
20impl Default for ResourceLimits {
21    fn default() -> Self {
22        Self {
23            memory_mb: 512,
24            cpu_cores: 1.0,
25            disk_io_mbps: 100,
26            network_io_mbps: 100,
27            execution_timeout: Duration::from_secs(3600), // 1 hour
28            idle_timeout: Duration::from_secs(300),       // 5 minutes
29        }
30    }
31}
32
33/// Current resource usage by an agent
34#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct ResourceUsage {
36    pub memory_used: usize,
37    pub cpu_utilization: f32,
38    pub disk_io_rate: usize,
39    pub network_io_rate: usize,
40    pub uptime: Duration,
41}
42
43impl Default for ResourceUsage {
44    fn default() -> Self {
45        Self {
46            memory_used: 0,
47            cpu_utilization: 0.0,
48            disk_io_rate: 0,
49            network_io_rate: 0,
50            uptime: Duration::from_secs(0),
51        }
52    }
53}
54
55/// Resource allocation for an agent
56#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct ResourceAllocation {
58    pub agent_id: AgentId,
59    pub allocated_memory: usize,
60    pub allocated_cpu_cores: f32,
61    pub allocated_disk_io: usize,
62    pub allocated_network_io: usize,
63    pub allocation_time: std::time::SystemTime,
64}
65
66/// System-wide resource pool
67#[derive(Debug, Clone, Serialize, Deserialize)]
68pub struct ResourcePool {
69    pub total_memory: usize,
70    pub total_cpu_cores: usize,
71    pub available_memory: usize,
72    pub available_cpu_cores: usize,
73    pub allocated_agents: HashMap<AgentId, ResourceAllocation>,
74}
75
76impl ResourcePool {
77    pub fn new(total_memory: usize, total_cpu_cores: usize) -> Self {
78        Self {
79            total_memory,
80            total_cpu_cores,
81            available_memory: total_memory,
82            available_cpu_cores: total_cpu_cores,
83            allocated_agents: HashMap::new(),
84        }
85    }
86
87    pub fn can_allocate(&self, limits: &ResourceLimits) -> bool {
88        self.available_memory >= limits.memory_mb
89            && self.available_cpu_cores >= limits.cpu_cores as usize
90    }
91
92    pub fn allocate(
93        &mut self,
94        agent_id: AgentId,
95        limits: &ResourceLimits,
96    ) -> Option<ResourceAllocation> {
97        if !self.can_allocate(limits) {
98            return None;
99        }
100
101        let allocation = ResourceAllocation {
102            agent_id,
103            allocated_memory: limits.memory_mb,
104            allocated_cpu_cores: limits.cpu_cores,
105            allocated_disk_io: limits.disk_io_mbps,
106            allocated_network_io: limits.network_io_mbps,
107            allocation_time: std::time::SystemTime::now(),
108        };
109
110        self.available_memory -= limits.memory_mb;
111        self.available_cpu_cores -= limits.cpu_cores as usize;
112        self.allocated_agents.insert(agent_id, allocation.clone());
113
114        Some(allocation)
115    }
116
117    pub fn deallocate(&mut self, agent_id: AgentId) -> Option<ResourceAllocation> {
118        if let Some(allocation) = self.allocated_agents.remove(&agent_id) {
119            self.available_memory += allocation.allocated_memory;
120            self.available_cpu_cores += allocation.allocated_cpu_cores as usize;
121            Some(allocation)
122        } else {
123            None
124        }
125    }
126
127    pub fn get_utilization(&self) -> ResourceUtilization {
128        let memory_utilization = if self.total_memory > 0 {
129            (self.total_memory - self.available_memory) as f32 / self.total_memory as f32
130        } else {
131            0.0
132        };
133
134        let cpu_utilization = if self.total_cpu_cores > 0 {
135            (self.total_cpu_cores as f32 - self.available_cpu_cores as f32)
136                / self.total_cpu_cores as f32
137        } else {
138            0.0
139        };
140
141        ResourceUtilization {
142            memory_utilization,
143            cpu_utilization,
144            active_agents: self.allocated_agents.len(),
145        }
146    }
147}
148
149/// Resource utilization metrics
150#[derive(Debug, Clone, Serialize, Deserialize)]
151pub struct ResourceUtilization {
152    pub memory_utilization: f32,
153    pub cpu_utilization: f32,
154    pub active_agents: usize,
155}
156
157/// Resource allocation strategies
158#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
159pub enum AllocationStrategy {
160    /// First available resource slot
161    FirstFit,
162    /// Optimal resource utilization
163    #[default]
164    BestFit,
165    /// Load balancing across resources
166    WorstFit,
167    /// Priority-based allocation
168    Priority,
169}
170
171/// Resource request from an agent
172#[derive(Debug, Clone, Serialize, Deserialize)]
173pub struct ResourceRequest {
174    pub agent_id: AgentId,
175    pub requested_limits: ResourceLimits,
176    pub priority: super::Priority,
177    pub justification: Option<String>,
178}
179
180/// Alert thresholds for resource monitoring
181#[derive(Debug, Clone, Serialize, Deserialize)]
182pub struct AlertThresholds {
183    pub memory_warning: f32,  // 80%
184    pub memory_critical: f32, // 95%
185    pub cpu_warning: f32,     // 80%
186    pub cpu_critical: f32,    // 95%
187}
188
189impl Default for AlertThresholds {
190    fn default() -> Self {
191        Self {
192            memory_warning: 0.8,
193            memory_critical: 0.95,
194            cpu_warning: 0.8,
195            cpu_critical: 0.95,
196        }
197    }
198}
199
200/// Resource monitoring configuration
201#[derive(Debug, Clone, Serialize, Deserialize)]
202pub struct ResourceMonitorConfig {
203    pub collection_interval: Duration,
204    pub alert_thresholds: AlertThresholds,
205    pub enable_detailed_metrics: bool,
206    pub metrics_retention_duration: Duration,
207}
208
209impl Default for ResourceMonitorConfig {
210    fn default() -> Self {
211        Self {
212            collection_interval: Duration::from_secs(30),
213            alert_thresholds: AlertThresholds::default(),
214            enable_detailed_metrics: true,
215            metrics_retention_duration: Duration::from_secs(86400), // 24 hours
216        }
217    }
218}