actr_runtime/
resource.rs

1//! Resource management
2
3use crate::error::{RuntimeError, RuntimeResult};
4use serde::{Deserialize, Serialize};
5
6/// Resource quota
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct ResourceQuota {
9    /// CPU quota(CPU cores)
10    pub cpu_cores: f64,
11
12    /// memory quota(bytes)
13    pub memory_bytes: u64,
14
15    /// network bandwidth quota(bytes/sec)
16    pub network_bandwidth_bps: u64,
17
18    /// disk IO quota(bytes/sec)
19    pub disk_io_bps: u64,
20}
21
22impl Default for ResourceQuota {
23    fn default() -> Self {
24        Self {
25            cpu_cores: 1.0,
26            memory_bytes: 1024 * 1024 * 1024,         // 1GB
27            network_bandwidth_bps: 100 * 1024 * 1024, // 100MB/s
28            disk_io_bps: 100 * 1024 * 1024,           // 100MB/s
29        }
30    }
31}
32
33/// Resource usage
34#[derive(Debug, Clone, Default, Serialize, Deserialize)]
35pub struct ResourceUsage {
36    /// CPU usage rate (0.0-1.0)
37    pub cpu_usage: f64,
38
39    /// memoryusingusage(bytes)
40    pub memory_used_bytes: u64,
41
42    /// network carry widthusingusage(bytes/sec)
43    pub network_usage_bps: u64,
44
45    /// disk IO usingusage(bytes/sec)
46    pub disk_io_bps: u64,
47}
48
49/// Resource configuration
50#[derive(Debug, Clone)]
51pub struct ResourceConfig {
52    /// whetherenable resourcelimit
53    pub enable_limits: bool,
54
55    /// resourcemonitoringinterval(seconds)
56    pub monitoring_interval_seconds: u64,
57
58    /// resourceusingWarningthreshold (0.0-1.0)
59    pub warning_threshold: f64,
60
61    /// resourceusinglimitthreshold (0.0-1.0)
62    pub limit_threshold: f64,
63}
64
65impl Default for ResourceConfig {
66    fn default() -> Self {
67        Self {
68            enable_limits: true,
69            monitoring_interval_seconds: 5,
70            warning_threshold: 0.8,
71            limit_threshold: 0.95,
72        }
73    }
74}
75
76/// Resource manager
77pub struct ResourceManager {
78    config: ResourceConfig,
79    quota: ResourceQuota,
80    current_usage: ResourceUsage,
81}
82
83impl ResourceManager {
84    /// Create newResource manager
85    pub fn new(config: ResourceConfig, quota: ResourceQuota) -> Self {
86        Self {
87            config,
88            quota,
89            current_usage: ResourceUsage::default(),
90        }
91    }
92
93    /// Checkresourcewhetheravailable
94    pub fn check_resource_availability(&self, required: &ResourceUsage) -> RuntimeResult<bool> {
95        if !self.config.enable_limits {
96            return Ok(true);
97        }
98
99        // Check CPU
100        let cpu_available =
101            self.quota.cpu_cores - (self.current_usage.cpu_usage * self.quota.cpu_cores);
102        if required.cpu_usage * self.quota.cpu_cores > cpu_available {
103            return Ok(false);
104        }
105
106        // Checkmemory
107        let memory_available = self.quota.memory_bytes - self.current_usage.memory_used_bytes;
108        if required.memory_used_bytes > memory_available {
109            return Ok(false);
110        }
111
112        Ok(true)
113    }
114
115    /// Allocateresource
116    pub fn allocate_resources(&mut self, usage: &ResourceUsage) -> RuntimeResult<()> {
117        if !self.check_resource_availability(usage)? {
118            return Err(RuntimeError::Unavailable {
119                message: "Insufficient resources available".to_string(),
120                target: None,
121            });
122        }
123
124        self.current_usage.cpu_usage += usage.cpu_usage;
125        self.current_usage.memory_used_bytes += usage.memory_used_bytes;
126        self.current_usage.network_usage_bps += usage.network_usage_bps;
127        self.current_usage.disk_io_bps += usage.disk_io_bps;
128
129        Ok(())
130    }
131
132    /// Releaseresource
133    pub fn release_resources(&mut self, usage: &ResourceUsage) -> RuntimeResult<()> {
134        self.current_usage.cpu_usage = (self.current_usage.cpu_usage - usage.cpu_usage).max(0.0);
135        self.current_usage.memory_used_bytes = self
136            .current_usage
137            .memory_used_bytes
138            .saturating_sub(usage.memory_used_bytes);
139        self.current_usage.network_usage_bps = self
140            .current_usage
141            .network_usage_bps
142            .saturating_sub(usage.network_usage_bps);
143        self.current_usage.disk_io_bps = self
144            .current_usage
145            .disk_io_bps
146            .saturating_sub(usage.disk_io_bps);
147
148        Ok(())
149    }
150
151    /// GetcurrentResource usage
152    pub fn get_usage(&self) -> &ResourceUsage {
153        &self.current_usage
154    }
155
156    /// GetResource quota
157    pub fn get_quota(&self) -> &ResourceQuota {
158        &self.quota
159    }
160
161    /// compute resourcesusage rate
162    pub fn calculate_usage_ratio(&self) -> ResourceUsageRatio {
163        ResourceUsageRatio {
164            cpu_ratio: self.current_usage.cpu_usage,
165            memory_ratio: self.current_usage.memory_used_bytes as f64
166                / self.quota.memory_bytes as f64,
167            network_ratio: self.current_usage.network_usage_bps as f64
168                / self.quota.network_bandwidth_bps as f64,
169            disk_ratio: self.current_usage.disk_io_bps as f64 / self.quota.disk_io_bps as f64,
170        }
171    }
172}
173
174/// resourceusage rate
175#[derive(Debug, Clone, Serialize, Deserialize)]
176pub struct ResourceUsageRatio {
177    /// CPU usage rate (0.0-1.0)
178    pub cpu_ratio: f64,
179
180    /// memoryusage rate (0.0-1.0)
181    pub memory_ratio: f64,
182
183    /// networkusage rate (0.0-1.0)
184    pub network_ratio: f64,
185
186    /// diskusage rate (0.0-1.0)
187    pub disk_ratio: f64,
188}