1use std::time::Duration;
37use serde::{Deserialize, Serialize};
38
39#[derive(
41 Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default,
42)]
43pub enum Environment {
44 #[default]
46 Development,
47 Testing,
49 Production,
51 Custom,
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct ProcessorConfig {
58 pub max_queue_size: usize,
60 pub max_concurrent_tasks: usize,
62 pub task_timeout: Duration,
64 pub max_retries: u32,
66 pub retry_delay: Duration,
68 pub cleanup_timeout: Duration,
70}
71
72impl Default for ProcessorConfig {
73 fn default() -> Self {
74 Self {
75 max_queue_size: 1000,
76 max_concurrent_tasks: 10,
77 task_timeout: Duration::from_secs(30),
78 max_retries: 3,
79 retry_delay: Duration::from_secs(1),
80 cleanup_timeout: Duration::from_secs(30),
81 }
82 }
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize)]
87pub struct PerformanceConfig {
88 pub enable_monitoring: bool,
90 pub middleware_timeout_ms: u64,
92 pub log_threshold_ms: u64,
94 pub task_receive_timeout_ms: u64,
96 pub enable_detailed_logging: bool,
98 pub metrics_sampling_rate: f64,
100}
101
102impl Default for PerformanceConfig {
103 fn default() -> Self {
104 Self {
105 enable_monitoring: false,
106 middleware_timeout_ms: 500,
107 log_threshold_ms: 50,
108 task_receive_timeout_ms: 5000,
109 enable_detailed_logging: false,
110 metrics_sampling_rate: 1.0,
111 }
112 }
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize)]
117pub struct EventConfig {
118 pub max_queue_size: usize,
120 pub handler_timeout: Duration,
122 pub enable_persistence: bool,
124 pub batch_size: usize,
126 pub max_concurrent_handlers: usize,
128}
129
130impl Default for EventConfig {
131 fn default() -> Self {
132 Self {
133 max_queue_size: 10000,
134 handler_timeout: Duration::from_secs(5),
135 enable_persistence: false,
136 batch_size: 100,
137 max_concurrent_handlers: 5,
138 }
139 }
140}
141
142#[derive(Debug, Clone, Serialize, Deserialize)]
144pub struct HistoryConfig {
145 pub max_entries: usize,
147 pub enable_compression: bool,
149 pub persistence_interval: Duration,
151}
152
153impl Default for HistoryConfig {
154 fn default() -> Self {
155 Self {
156 max_entries: 100,
157 enable_compression: false,
158 persistence_interval: Duration::from_secs(60),
159 }
160 }
161}
162
163#[derive(Debug, Clone, Serialize, Deserialize)]
165pub struct ExtensionConfig {
166 pub load_timeout: Duration,
168 pub enable_hot_reload: bool,
170 pub max_memory_mb: usize,
172 pub enable_sandbox: bool,
174 pub xml_schema_paths: Vec<String>,
176 pub enable_xml_auto_reload: bool,
178 pub xml_parse_timeout: Duration,
180}
181
182impl Default for ExtensionConfig {
183 fn default() -> Self {
184 Self {
185 load_timeout: Duration::from_secs(10),
186 enable_hot_reload: false,
187 max_memory_mb: 100,
188 enable_sandbox: true,
189 xml_schema_paths: Vec::new(),
190 enable_xml_auto_reload: false,
191 xml_parse_timeout: Duration::from_secs(5),
192 }
193 }
194}
195
196#[derive(Debug, Clone, Serialize, Deserialize)]
198pub struct CacheConfig {
199 pub max_entries: usize,
201 pub entry_ttl: Duration,
203 pub enable_lru: bool,
205 pub cleanup_interval: Duration,
207}
208
209impl Default for CacheConfig {
210 fn default() -> Self {
211 Self {
212 max_entries: 1000,
213 entry_ttl: Duration::from_secs(300), enable_lru: true,
215 cleanup_interval: Duration::from_secs(60),
216 }
217 }
218}
219
220#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
222pub enum RuntimeType {
223 Auto,
225 Sync,
227 Async,
229 Actor,
231}
232
233impl Default for RuntimeType {
234 fn default() -> Self {
235 RuntimeType::Auto
236 }
237}
238
239#[derive(Debug, Clone, Serialize, Deserialize, Default)]
241pub struct RuntimeConfig {
242 #[serde(default)]
244 pub runtime_type: RuntimeType,
245}
246
247#[derive(Debug, Clone, Serialize, Deserialize, Default)]
249pub struct ForgeConfig {
250 #[serde(default)]
252 pub environment: Environment,
253 #[serde(default)]
255 pub runtime: RuntimeConfig,
256 #[serde(default)]
258 pub processor: ProcessorConfig,
259 #[serde(default)]
261 pub performance: PerformanceConfig,
262 #[serde(default)]
264 pub event: EventConfig,
265 #[serde(default)]
267 pub history: HistoryConfig,
268 #[serde(default)]
270 pub extension: ExtensionConfig,
271 #[serde(default)]
273 pub cache: CacheConfig,
274}
275
276impl ForgeConfig {
277 pub fn for_environment(env: Environment) -> Self {
279 match env {
280 Environment::Development => Self::development(),
281 Environment::Testing => Self::testing(),
282 Environment::Production => Self::production(),
283 Environment::Custom => Self::default(),
284 }
285 }
286
287 pub fn development() -> Self {
289 Self {
290 environment: Environment::Development,
291 runtime: RuntimeConfig::default(),
292 processor: ProcessorConfig {
293 max_queue_size: 500,
294 max_concurrent_tasks: 5,
295 task_timeout: Duration::from_secs(60),
296 max_retries: 5,
297 retry_delay: Duration::from_secs(2),
298 cleanup_timeout: Duration::from_secs(60),
299 },
300 performance: PerformanceConfig {
301 enable_monitoring: true,
302 middleware_timeout_ms: 10000, log_threshold_ms: 100,
304 task_receive_timeout_ms: 30000, enable_detailed_logging: true,
306 metrics_sampling_rate: 1.0,
307 },
308 event: EventConfig {
309 max_queue_size: 5000,
310 handler_timeout: Duration::from_secs(10),
311 enable_persistence: false,
312 batch_size: 50,
313 max_concurrent_handlers: 3,
314 },
315 history: HistoryConfig {
316 max_entries: 200,
317 enable_compression: false,
318 persistence_interval: Duration::from_secs(30),
319 },
320 extension: ExtensionConfig {
321 load_timeout: Duration::from_secs(30),
322 enable_hot_reload: true,
323 max_memory_mb: 200,
324 enable_sandbox: false, xml_schema_paths: Vec::new(),
326 enable_xml_auto_reload: true,
327 xml_parse_timeout: Duration::from_secs(10),
328 },
329 cache: CacheConfig {
330 max_entries: 500,
331 entry_ttl: Duration::from_secs(600), enable_lru: true,
333 cleanup_interval: Duration::from_secs(30),
334 },
335 }
336 }
337
338 pub fn testing() -> Self {
340 Self {
341 environment: Environment::Testing,
342 runtime: RuntimeConfig::default(),
343 processor: ProcessorConfig {
344 max_queue_size: 100,
345 max_concurrent_tasks: 3,
346 task_timeout: Duration::from_secs(10),
347 max_retries: 2,
348 retry_delay: Duration::from_millis(500),
349 cleanup_timeout: Duration::from_secs(10),
350 },
351 performance: PerformanceConfig {
352 enable_monitoring: true,
353 middleware_timeout_ms: 2000, log_threshold_ms: 50,
355 task_receive_timeout_ms: 5000, enable_detailed_logging: false,
357 metrics_sampling_rate: 0.1, },
359 event: EventConfig {
360 max_queue_size: 1000,
361 handler_timeout: Duration::from_secs(2),
362 enable_persistence: false,
363 batch_size: 20,
364 max_concurrent_handlers: 2,
365 },
366 history: HistoryConfig {
367 max_entries: 50,
368 enable_compression: false,
369 persistence_interval: Duration::from_secs(10),
370 },
371 extension: ExtensionConfig {
372 load_timeout: Duration::from_secs(5),
373 enable_hot_reload: false,
374 max_memory_mb: 50,
375 enable_sandbox: true,
376 xml_schema_paths: Vec::new(),
377 enable_xml_auto_reload: false,
378 xml_parse_timeout: Duration::from_secs(3),
379 },
380 cache: CacheConfig {
381 max_entries: 100,
382 entry_ttl: Duration::from_secs(60), enable_lru: true,
384 cleanup_interval: Duration::from_secs(10),
385 },
386 }
387 }
388
389 pub fn production() -> Self {
391 Self {
392 environment: Environment::Production,
393 runtime: RuntimeConfig::default(),
394 processor: ProcessorConfig {
395 max_queue_size: 10000,
396 max_concurrent_tasks: 50,
397 task_timeout: Duration::from_secs(30),
398 max_retries: 3,
399 retry_delay: Duration::from_millis(100),
400 cleanup_timeout: Duration::from_secs(30),
401 },
402 performance: PerformanceConfig {
403 enable_monitoring: true,
404 middleware_timeout_ms: 1000, log_threshold_ms: 50,
406 task_receive_timeout_ms: 5000, enable_detailed_logging: false,
408 metrics_sampling_rate: 0.01, },
410 event: EventConfig {
411 max_queue_size: 50000,
412 handler_timeout: Duration::from_secs(5),
413 enable_persistence: true,
414 batch_size: 500,
415 max_concurrent_handlers: 10,
416 },
417 history: HistoryConfig {
418 max_entries: 1000,
419 enable_compression: true,
420 persistence_interval: Duration::from_secs(300), },
422 extension: ExtensionConfig {
423 load_timeout: Duration::from_secs(10),
424 enable_hot_reload: false,
425 max_memory_mb: 500,
426 enable_sandbox: true,
427 xml_schema_paths: Vec::new(),
428 enable_xml_auto_reload: false,
429 xml_parse_timeout: Duration::from_secs(5),
430 },
431 cache: CacheConfig {
432 max_entries: 10000,
433 entry_ttl: Duration::from_secs(1800), enable_lru: true,
435 cleanup_interval: Duration::from_secs(300), },
437 }
438 }
439
440 pub fn builder() -> ForgeConfigBuilder {
442 ForgeConfigBuilder::new()
443 }
444
445 pub fn validate(&self) -> Result<(), ConfigValidationError> {
447 if self.processor.max_queue_size == 0 {
449 return Err(ConfigValidationError::InvalidValue {
450 field: "processor.max_queue_size".to_string(),
451 value: "0".to_string(),
452 reason: "队列大小必须大于0".to_string(),
453 });
454 }
455
456 if self.processor.max_concurrent_tasks == 0 {
457 return Err(ConfigValidationError::InvalidValue {
458 field: "processor.max_concurrent_tasks".to_string(),
459 value: "0".to_string(),
460 reason: "并发任务数必须大于0".to_string(),
461 });
462 }
463
464 if self.processor.task_timeout.is_zero() {
465 return Err(ConfigValidationError::InvalidValue {
466 field: "processor.task_timeout".to_string(),
467 value: "0".to_string(),
468 reason: "任务超时时间必须大于0".to_string(),
469 });
470 }
471
472 if self.performance.middleware_timeout_ms == 0 {
474 return Err(ConfigValidationError::InvalidValue {
475 field: "performance.middleware_timeout_ms".to_string(),
476 value: "0".to_string(),
477 reason: "中间件超时时间必须大于0".to_string(),
478 });
479 }
480
481 if !(0.0..=1.0).contains(&self.performance.metrics_sampling_rate) {
482 return Err(ConfigValidationError::InvalidValue {
483 field: "performance.metrics_sampling_rate".to_string(),
484 value: self.performance.metrics_sampling_rate.to_string(),
485 reason: "采样率必须在0.0到1.0之间".to_string(),
486 });
487 }
488
489 if self.event.max_queue_size == 0 {
491 return Err(ConfigValidationError::InvalidValue {
492 field: "event.max_queue_size".to_string(),
493 value: "0".to_string(),
494 reason: "事件队列大小必须大于0".to_string(),
495 });
496 }
497
498 if self.history.max_entries == 0 {
500 return Err(ConfigValidationError::InvalidValue {
501 field: "history.max_entries".to_string(),
502 value: "0".to_string(),
503 reason: "历史记录条数必须大于0".to_string(),
504 });
505 }
506
507 if self.cache.max_entries == 0 {
509 return Err(ConfigValidationError::InvalidValue {
510 field: "cache.max_entries".to_string(),
511 value: "0".to_string(),
512 reason: "缓存条目数必须大于0".to_string(),
513 });
514 }
515
516 Ok(())
517 }
518
519 pub fn get_tuning_suggestions(&self) -> Vec<String> {
521 let mut suggestions = Vec::new();
522
523 match self.environment {
524 Environment::Development => {
525 if !self.performance.enable_detailed_logging {
526 suggestions
527 .push("开发环境建议启用详细日志记录".to_string());
528 }
529 if self.extension.enable_sandbox {
530 suggestions
531 .push("开发环境可以关闭扩展沙箱以便调试".to_string());
532 }
533 },
534 Environment::Production => {
535 if self.performance.enable_detailed_logging {
536 suggestions.push(
537 "生产环境建议关闭详细日志记录以提高性能".to_string(),
538 );
539 }
540 if self.performance.metrics_sampling_rate > 0.1 {
541 suggestions.push(
542 "生产环境建议降低指标采样率以减少开销".to_string(),
543 );
544 }
545 if !self.extension.enable_sandbox {
546 suggestions.push(
547 "生产环境建议启用扩展沙箱以提高安全性".to_string(),
548 );
549 }
550 },
551 Environment::Testing => {
552 if self.processor.task_timeout > Duration::from_secs(30) {
553 suggestions
554 .push("测试环境建议使用较短的任务超时时间".to_string());
555 }
556 },
557 Environment::Custom => {
558 suggestions
559 .push("自定义环境,请根据实际需求调整配置".to_string());
560 },
561 }
562
563 suggestions
564 }
565}
566
567#[derive(Debug, Clone)]
569pub enum ConfigValidationError {
570 InvalidValue { field: String, value: String, reason: String },
572 Conflict { field1: String, field2: String, reason: String },
574 MissingRequired { field: String },
576}
577
578impl std::fmt::Display for ConfigValidationError {
579 fn fmt(
580 &self,
581 f: &mut std::fmt::Formatter<'_>,
582 ) -> std::fmt::Result {
583 match self {
584 ConfigValidationError::InvalidValue { field, value, reason } => {
585 write!(f, "配置字段 '{field}' 的值 '{value}' 无效: {reason}")
586 },
587 ConfigValidationError::Conflict { field1, field2, reason } => {
588 write!(f, "配置字段 '{field1}' 和 '{field2}' 冲突: {reason}")
589 },
590 ConfigValidationError::MissingRequired { field } => {
591 write!(f, "缺少必需的配置字段: {field}")
592 },
593 }
594 }
595}
596
597impl std::error::Error for ConfigValidationError {}
598
599#[derive(Debug, Clone)]
601pub struct ForgeConfigBuilder {
602 config: ForgeConfig,
603}
604
605impl ForgeConfigBuilder {
606 pub fn new() -> Self {
608 Self { config: ForgeConfig::default() }
609 }
610
611 pub fn from_config(config: ForgeConfig) -> Self {
613 Self { config }
614 }
615
616 pub fn environment(
618 mut self,
619 env: Environment,
620 ) -> Self {
621 self.config.environment = env;
622 self
623 }
624
625 pub fn processor_config(
627 mut self,
628 config: ProcessorConfig,
629 ) -> Self {
630 self.config.processor = config;
631 self
632 }
633
634 pub fn performance_config(
636 mut self,
637 config: PerformanceConfig,
638 ) -> Self {
639 self.config.performance = config;
640 self
641 }
642
643 pub fn event_config(
645 mut self,
646 config: EventConfig,
647 ) -> Self {
648 self.config.event = config;
649 self
650 }
651
652 pub fn history_config(
654 mut self,
655 config: HistoryConfig,
656 ) -> Self {
657 self.config.history = config;
658 self
659 }
660
661 pub fn extension_config(
663 mut self,
664 config: ExtensionConfig,
665 ) -> Self {
666 self.config.extension = config;
667 self
668 }
669
670 pub fn cache_config(
672 mut self,
673 config: CacheConfig,
674 ) -> Self {
675 self.config.cache = config;
676 self
677 }
678
679 pub fn max_queue_size(
681 mut self,
682 size: usize,
683 ) -> Self {
684 self.config.processor.max_queue_size = size;
685 self
686 }
687
688 pub fn max_concurrent_tasks(
690 mut self,
691 count: usize,
692 ) -> Self {
693 self.config.processor.max_concurrent_tasks = count;
694 self
695 }
696
697 pub fn task_timeout(
699 mut self,
700 timeout: Duration,
701 ) -> Self {
702 self.config.processor.task_timeout = timeout;
703 self
704 }
705
706 pub fn middleware_timeout(
708 mut self,
709 timeout_ms: u64,
710 ) -> Self {
711 self.config.performance.middleware_timeout_ms = timeout_ms;
712 self
713 }
714
715 pub fn enable_monitoring(
717 mut self,
718 enable: bool,
719 ) -> Self {
720 self.config.performance.enable_monitoring = enable;
721 self
722 }
723
724 pub fn history_limit(
726 mut self,
727 limit: usize,
728 ) -> Self {
729 self.config.history.max_entries = limit;
730 self
731 }
732
733 pub fn build(self) -> Result<ForgeConfig, ConfigValidationError> {
735 self.config.validate()?;
736 Ok(self.config)
737 }
738
739 pub fn build_unchecked(self) -> ForgeConfig {
741 self.config
742 }
743}
744
745impl Default for ForgeConfigBuilder {
746 fn default() -> Self {
747 Self::new()
748 }
749}
750
751impl ForgeConfig {
753 pub fn from_json(json: &str) -> Result<Self, serde_json::Error> {
755 serde_json::from_str(json)
756 }
757
758 pub fn to_json(&self) -> Result<String, serde_json::Error> {
760 serde_json::to_string_pretty(self)
761 }
762
763 pub fn from_env_override(mut self) -> Self {
772 use std::env;
773
774 if let Ok(env_str) = env::var("FORGE_ENVIRONMENT") {
776 match env_str.to_lowercase().as_str() {
777 "development" | "dev" => {
778 self.environment = Environment::Development
779 },
780 "testing" | "test" => self.environment = Environment::Testing,
781 "production" | "prod" => {
782 self.environment = Environment::Production
783 },
784 "custom" => self.environment = Environment::Custom,
785 _ => {},
786 }
787 }
788
789 if let Ok(size) = env::var("FORGE_PROCESSOR_MAX_QUEUE_SIZE") {
791 if let Ok(size) = size.parse::<usize>() {
792 self.processor.max_queue_size = size;
793 }
794 }
795
796 if let Ok(tasks) = env::var("FORGE_PROCESSOR_MAX_CONCURRENT_TASKS") {
797 if let Ok(tasks) = tasks.parse::<usize>() {
798 self.processor.max_concurrent_tasks = tasks;
799 }
800 }
801
802 if let Ok(enable) = env::var("FORGE_PERFORMANCE_ENABLE_MONITORING") {
804 self.performance.enable_monitoring =
805 enable.to_lowercase() == "true";
806 }
807
808 if let Ok(timeout) = env::var("FORGE_PERFORMANCE_MIDDLEWARE_TIMEOUT_MS")
809 {
810 if let Ok(timeout) = timeout.parse::<u64>() {
811 self.performance.middleware_timeout_ms = timeout;
812 }
813 }
814
815 self
816 }
817
818 pub fn merge_with(
820 mut self,
821 other: &ForgeConfig,
822 ) -> Self {
823 if other.environment != Environment::Development {
826 self.environment = other.environment;
827 }
828
829 self.processor = other.processor.clone();
831 self.performance = other.performance.clone();
832 self.event = other.event.clone();
833 self.history = other.history.clone();
834 self.extension = other.extension.clone();
835 self.cache = other.cache.clone();
836
837 self
838 }
839}