mf_core/runtime/
adaptive.rs

1//! 自适应运行时选择器
2//!
3//! 根据系统资源(CPU核心数、内存大小)自动:
4//! 1. 选择最合适的运行时类型(Sync/Async/Actor)
5//! 2. 生成优化的运行时配置参数
6//! 3. 调整并发数、队列大小等性能参数
7//!
8//! # 策略说明
9//!
10//! ## 运行时选择策略
11//! - **低配** (<4核 或 <8GB): Sync运行时(开销最小)
12//! - **中配** (4-7核 + 8-15GB): Async运行时(平衡性能和开销)
13//! - **高配** (≥8核 + ≥16GB): Actor运行时(最大并发能力)
14//!
15//! ## 配置优化策略
16//! - 并发任务数 = CPU线程数 × 75%
17//! - 队列大小 = 可用内存GB × 100(限制在500-10000之间)
18//! - 超时配置根据资源等级调整
19//!
20//! # 使用示例
21//!
22//! ```rust
23//! use mf_core::runtime::adaptive::AdaptiveRuntimeSelector;
24//! use mf_core::runtime::system_detector::SystemResources;
25//!
26//! let resources = SystemResources::detect();
27//! let runtime_type = AdaptiveRuntimeSelector::select_runtime(&resources);
28//! let config = AdaptiveRuntimeSelector::generate_config(&resources);
29//! ```
30
31use std::time::Duration;
32
33use crate::config::{
34    CacheConfig, EventConfig, ExtensionConfig, ForgeConfig, HistoryConfig,
35    PerformanceConfig, ProcessorConfig, RuntimeConfig, RuntimeType,
36};
37
38use super::system_detector::{ResourceTier, SystemResources};
39
40/// 自适应运行时选择器
41pub struct AdaptiveRuntimeSelector;
42
43impl AdaptiveRuntimeSelector {
44    /// 根据系统资源选择最优运行时类型
45    ///
46    /// # 选择策略
47    /// - **Low**: 同步运行时(开销最小,适合低配机器)
48    /// - **Medium**: 异步运行时(平衡性能和开销)
49    /// - **High**: Actor运行时(最大并发能力)
50    ///
51    /// # 参数
52    /// * `resources` - 系统资源信息
53    ///
54    /// # 返回值
55    /// * `RuntimeType` - 推荐的运行时类型
56    ///
57    /// # 示例
58    /// ```rust
59    /// let resources = SystemResources::detect();
60    /// let runtime_type = AdaptiveRuntimeSelector::select_runtime(&resources);
61    /// println!("推荐运行时: {:?}", runtime_type);
62    /// ```
63    pub fn select_runtime(resources: &SystemResources) -> RuntimeType {
64        match resources.resource_tier() {
65            ResourceTier::Low => RuntimeType::Sync,
66            ResourceTier::Medium => RuntimeType::Async,
67            ResourceTier::High => RuntimeType::Actor,
68        }
69    }
70
71    /// 根据系统资源生成优化的运行时配置
72    ///
73    /// 自动调整以下参数:
74    /// - 并发任务数(基于CPU线程数)
75    /// - 队列大小(基于可用内存)
76    /// - 超时配置(基于资源等级)
77    /// - 监控采样率(基于资源等级)
78    ///
79    /// # 参数
80    /// * `resources` - 系统资源信息
81    ///
82    /// # 返回值
83    /// * `ForgeConfig` - 优化后的配置
84    ///
85    /// # 示例
86    /// ```rust
87    /// let resources = SystemResources::detect();
88    /// let config = AdaptiveRuntimeSelector::generate_config(&resources);
89    /// println!("并发任务数: {}", config.processor.max_concurrent_tasks);
90    /// ```
91    pub fn generate_config(resources: &SystemResources) -> ForgeConfig {
92        let tier = resources.resource_tier();
93
94        ForgeConfig {
95            runtime: RuntimeConfig {
96                runtime_type: Self::select_runtime(resources),
97            },
98            processor: Self::processor_config(resources, tier),
99            performance: Self::performance_config(resources, tier),
100            event: Self::event_config(resources, tier),
101            history: Self::history_config(resources, tier),
102            extension: ExtensionConfig::default(),
103            cache: Self::cache_config(resources, tier),
104            ..Default::default()
105        }
106    }
107
108    /// 生成处理器配置
109    ///
110    /// 根据CPU和内存资源优化:
111    /// - 并发任务数 = CPU线程数 × 75%(至少2个)
112    /// - 队列大小 = 根据可用内存计算
113    /// - 超时时间 = 根据资源等级调整
114    fn processor_config(
115        res: &SystemResources,
116        tier: ResourceTier,
117    ) -> ProcessorConfig {
118        ProcessorConfig {
119            // 队列大小:根据内存自适应
120            max_queue_size: Self::calc_queue_size(res.available_memory_mb),
121
122            // 并发任务数:CPU线程数的75%(留一些余量,至少2个)
123            max_concurrent_tasks: ((res.cpu_threads as f32 * 0.75) as usize)
124                .max(2),
125
126            // 任务超时:高配机器超时更短(期望更快响应)
127            task_timeout: match tier {
128                ResourceTier::High => Duration::from_secs(10),
129                ResourceTier::Medium => Duration::from_secs(30),
130                ResourceTier::Low => Duration::from_secs(60),
131            },
132
133            // 重试次数:低配机器给更多重试机会
134            max_retries: match tier {
135                ResourceTier::High => 3,
136                ResourceTier::Medium => 3,
137                ResourceTier::Low => 5,
138            },
139
140            retry_delay: Duration::from_secs(1),
141            cleanup_timeout: Duration::from_secs(30),
142        }
143    }
144
145    /// 生成性能监控配置
146    ///
147    /// 优化策略:
148    /// - 高配机器启用详细监控
149    /// - 低配机器降低采样率减少开销
150    /// - 中间件超时根据CPU性能调整
151    fn performance_config(
152        _res: &SystemResources,
153        tier: ResourceTier,
154    ) -> PerformanceConfig {
155        PerformanceConfig {
156            // 高配机器启用详细监控
157            enable_monitoring: tier == ResourceTier::High,
158            enable_detailed_logging: tier == ResourceTier::High,
159
160            // 中间件超时:根据CPU性能调整
161            middleware_timeout_ms: match tier {
162                ResourceTier::High => 300,   // 高配期望更快
163                ResourceTier::Medium => 500, // 中配标准超时
164                ResourceTier::Low => 1000,   // 低配给更多时间
165            },
166
167            // 日志阈值:高配更敏感
168            log_threshold_ms: match tier {
169                ResourceTier::High => 50,
170                ResourceTier::Medium => 100,
171                ResourceTier::Low => 200,
172            },
173
174            // 任务接收超时
175            task_receive_timeout_ms: match tier {
176                ResourceTier::High => 3000,
177                ResourceTier::Medium => 5000,
178                ResourceTier::Low => 10000,
179            },
180
181            // 采样率:低配机器降低采样减少开销
182            metrics_sampling_rate: match tier {
183                ResourceTier::High => 1.0,   // 全采样
184                ResourceTier::Medium => 0.5, // 50%采样
185                ResourceTier::Low => 0.1,    // 10%采样
186            },
187        }
188    }
189
190    /// 生成事件系统配置
191    ///
192    /// 优化策略:
193    /// - 事件队列大小基于内存
194    /// - 并发处理器数基于CPU核心数
195    /// - 批处理大小根据资源等级调整
196    fn event_config(
197        res: &SystemResources,
198        tier: ResourceTier,
199    ) -> EventConfig {
200        EventConfig {
201            // 事件队列:队列大小的一半
202            max_queue_size: Self::calc_queue_size(res.available_memory_mb) / 2,
203
204            // 处理器超时:与中间件超时一致
205            handler_timeout: Duration::from_millis(match tier {
206                ResourceTier::High => 300,
207                ResourceTier::Medium => 500,
208                ResourceTier::Low => 1000,
209            }),
210
211            // 持久化:低配机器默认不启用
212            enable_persistence: tier == ResourceTier::High,
213
214            // 批处理大小:高配用更大批次提升吞吐
215            batch_size: match tier {
216                ResourceTier::High => 200,
217                ResourceTier::Medium => 100,
218                ResourceTier::Low => 50,
219            },
220
221            // 并发处理器数:核心数的一半(至少1个)
222            max_concurrent_handlers: (res.cpu_cores / 2).max(1),
223        }
224    }
225
226    /// 生成历史记录配置
227    ///
228    /// 优化策略:
229    /// - 历史记录数根据可用内存
230    /// - 低配机器启用压缩节省内存
231    fn history_config(
232        _res: &SystemResources,
233        tier: ResourceTier,
234    ) -> HistoryConfig {
235        HistoryConfig {
236            // 历史记录数:根据资源等级
237            max_entries: match tier {
238                ResourceTier::High => 1000,
239                ResourceTier::Medium => 500,
240                ResourceTier::Low => 100,
241            },
242
243            // 低配机器启用压缩节省内存
244            enable_compression: tier == ResourceTier::Low,
245
246            // 持久化间隔:高配更频繁
247            persistence_interval: Duration::from_secs(match tier {
248                ResourceTier::High => 30,
249                ResourceTier::Medium => 60,
250                ResourceTier::Low => 120,
251            }),
252        }
253    }
254
255    /// 生成缓存配置
256    fn cache_config(
257        _res: &SystemResources,
258        tier: ResourceTier,
259    ) -> CacheConfig {
260        CacheConfig {
261            // 缓存条目数:根据资源等级
262            max_entries: match tier {
263                ResourceTier::High => 5000,
264                ResourceTier::Medium => 2000,
265                ResourceTier::Low => 500,
266            },
267
268            // TTL:高配缓存时间更短(数据更新及时)
269            entry_ttl: Duration::from_secs(match tier {
270                ResourceTier::High => 180,   // 3分钟
271                ResourceTier::Medium => 300, // 5分钟
272                ResourceTier::Low => 600,    // 10分钟
273            }),
274
275            enable_lru: true,
276
277            // 清理间隔
278            cleanup_interval: Duration::from_secs(60),
279        }
280    }
281
282    /// 计算队列大小
283    ///
284    /// 策略:每GB可用内存 = 100个队列槽位
285    /// 限制范围:500 - 10000
286    ///
287    /// # 参数
288    /// * `available_memory_mb` - 可用内存(MB)
289    ///
290    /// # 返回值
291    /// * `usize` - 计算出的队列大小
292    fn calc_queue_size(available_memory_mb: u64) -> usize {
293        let memory_gb = (available_memory_mb / 1024).max(1);
294        (memory_gb as usize * 100).clamp(500, 10000)
295    }
296}
297
298#[cfg(test)]
299mod tests {
300    use super::*;
301
302    #[test]
303    fn test_select_runtime() {
304        // 低配 -> Sync
305        let low = SystemResources {
306            cpu_cores: 2,
307            cpu_threads: 2,
308            total_memory_mb: 4096,
309            available_memory_mb: 2048,
310        };
311        assert_eq!(
312            AdaptiveRuntimeSelector::select_runtime(&low),
313            RuntimeType::Sync
314        );
315
316        // 中配 -> Async
317        let medium = SystemResources {
318            cpu_cores: 4,
319            cpu_threads: 8,
320            total_memory_mb: 8192,
321            available_memory_mb: 4096,
322        };
323        assert_eq!(
324            AdaptiveRuntimeSelector::select_runtime(&medium),
325            RuntimeType::Async
326        );
327
328        // 高配 -> Actor
329        let high = SystemResources {
330            cpu_cores: 8,
331            cpu_threads: 16,
332            total_memory_mb: 16384,
333            available_memory_mb: 8192,
334        };
335        assert_eq!(
336            AdaptiveRuntimeSelector::select_runtime(&high),
337            RuntimeType::Actor
338        );
339    }
340
341    #[test]
342    fn test_calc_queue_size() {
343        // 2GB -> 200 (但限制最小500)
344        assert_eq!(AdaptiveRuntimeSelector::calc_queue_size(2048), 500);
345
346        // 4GB -> 400 (但限制最小500)
347        assert_eq!(AdaptiveRuntimeSelector::calc_queue_size(4096), 500);
348
349        // 8GB -> 800
350        assert_eq!(AdaptiveRuntimeSelector::calc_queue_size(8192), 800);
351
352        // 16GB -> 1600
353        assert_eq!(AdaptiveRuntimeSelector::calc_queue_size(16384), 1600);
354
355        // 128GB -> 12800 (但限制最大10000)
356        assert_eq!(AdaptiveRuntimeSelector::calc_queue_size(128 * 1024), 10000);
357    }
358
359    #[test]
360    fn test_generate_config() {
361        let resources = SystemResources {
362            cpu_cores: 4,
363            cpu_threads: 8,
364            total_memory_mb: 8192,
365            available_memory_mb: 4096,
366        };
367
368        let config = AdaptiveRuntimeSelector::generate_config(&resources);
369
370        // 验证运行时选择
371        assert_eq!(config.runtime.runtime_type, RuntimeType::Async);
372
373        // 验证并发数:8 * 0.75 = 6
374        assert_eq!(config.processor.max_concurrent_tasks, 6);
375
376        // 验证队列大小:4GB = 400 -> 500(最小限制)
377        assert_eq!(config.processor.max_queue_size, 500);
378
379        // 验证中配超时
380        assert_eq!(config.performance.middleware_timeout_ms, 500);
381    }
382
383    #[test]
384    fn test_concurrent_tasks_calculation() {
385        // 测试最小值限制
386        let low = SystemResources {
387            cpu_cores: 1,
388            cpu_threads: 1,
389            total_memory_mb: 2048,
390            available_memory_mb: 1024,
391        };
392        let config = AdaptiveRuntimeSelector::generate_config(&low);
393        assert!(
394            config.processor.max_concurrent_tasks >= 2,
395            "并发数应该至少为2"
396        );
397
398        // 测试正常计算
399        let medium = SystemResources {
400            cpu_cores: 4,
401            cpu_threads: 8,
402            total_memory_mb: 8192,
403            available_memory_mb: 4096,
404        };
405        let config = AdaptiveRuntimeSelector::generate_config(&medium);
406        assert_eq!(config.processor.max_concurrent_tasks, 6, "8 * 0.75 = 6");
407    }
408}