xerv_core/flow/
settings.rs1use serde::{Deserialize, Serialize};
4use std::time::Duration;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
11#[serde(default)]
12pub struct FlowSettings {
13 #[serde(default = "default_max_concurrent")]
15 pub max_concurrent_executions: u32,
16
17 #[serde(default = "default_timeout_ms")]
19 pub execution_timeout_ms: u64,
20
21 #[serde(default = "default_circuit_breaker_threshold")]
23 pub circuit_breaker_threshold: f64,
24
25 #[serde(default = "default_circuit_breaker_window_ms")]
27 pub circuit_breaker_window_ms: u64,
28
29 #[serde(default = "default_max_concurrent_versions")]
31 pub max_concurrent_versions: u32,
32
33 #[serde(default = "default_drain_timeout_ms")]
35 pub drain_timeout_ms: u64,
36
37 #[serde(default = "default_drain_grace_period_ms")]
39 pub drain_grace_period_ms: u64,
40
41 #[serde(default)]
43 pub debug: bool,
44
45 #[serde(default)]
47 pub env: std::collections::HashMap<String, String>,
48}
49
50fn default_max_concurrent() -> u32 {
51 100
52}
53fn default_timeout_ms() -> u64 {
54 60_000
55}
56fn default_circuit_breaker_threshold() -> f64 {
57 0.05
58}
59fn default_circuit_breaker_window_ms() -> u64 {
60 60_000
61}
62fn default_max_concurrent_versions() -> u32 {
63 5
64}
65fn default_drain_timeout_ms() -> u64 {
66 30 * 60 * 1000
67}
68fn default_drain_grace_period_ms() -> u64 {
69 5 * 60 * 1000
70}
71
72impl Default for FlowSettings {
73 fn default() -> Self {
74 Self {
75 max_concurrent_executions: default_max_concurrent(),
76 execution_timeout_ms: default_timeout_ms(),
77 circuit_breaker_threshold: default_circuit_breaker_threshold(),
78 circuit_breaker_window_ms: default_circuit_breaker_window_ms(),
79 max_concurrent_versions: default_max_concurrent_versions(),
80 drain_timeout_ms: default_drain_timeout_ms(),
81 drain_grace_period_ms: default_drain_grace_period_ms(),
82 debug: false,
83 env: std::collections::HashMap::new(),
84 }
85 }
86}
87
88impl FlowSettings {
89 pub fn execution_timeout(&self) -> Duration {
91 Duration::from_millis(self.execution_timeout_ms)
92 }
93
94 pub fn circuit_breaker_window(&self) -> Duration {
96 Duration::from_millis(self.circuit_breaker_window_ms)
97 }
98
99 pub fn drain_timeout(&self) -> Duration {
101 Duration::from_millis(self.drain_timeout_ms)
102 }
103
104 pub fn drain_grace_period(&self) -> Duration {
106 Duration::from_millis(self.drain_grace_period_ms)
107 }
108
109 pub fn to_pipeline_settings(&self) -> crate::traits::PipelineSettings {
111 crate::traits::PipelineSettings {
112 max_concurrent_executions: self.max_concurrent_executions,
113 execution_timeout: self.execution_timeout(),
114 circuit_breaker_threshold: self.circuit_breaker_threshold,
115 circuit_breaker_window: self.circuit_breaker_window(),
116 max_concurrent_versions: self.max_concurrent_versions,
117 drain_timeout: self.drain_timeout(),
118 drain_grace_period: self.drain_grace_period(),
119 }
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126
127 #[test]
128 fn default_settings() {
129 let settings = FlowSettings::default();
130 assert_eq!(settings.max_concurrent_executions, 100);
131 assert_eq!(settings.execution_timeout_ms, 60_000);
132 assert_eq!(settings.circuit_breaker_threshold, 0.05);
133 }
134
135 #[test]
136 fn deserialize_settings() {
137 let yaml = r#"
138max_concurrent_executions: 50
139execution_timeout_ms: 30000
140debug: true
141env:
142 API_KEY: test123
143"#;
144 let settings: FlowSettings = serde_yaml::from_str(yaml).unwrap();
145 assert_eq!(settings.max_concurrent_executions, 50);
146 assert_eq!(settings.execution_timeout_ms, 30_000);
147 assert!(settings.debug);
148 assert_eq!(settings.env.get("API_KEY"), Some(&"test123".to_string()));
149 }
150
151 #[test]
152 fn to_duration() {
153 let settings = FlowSettings {
154 execution_timeout_ms: 5000,
155 ..Default::default()
156 };
157 assert_eq!(settings.execution_timeout(), Duration::from_millis(5000));
158 }
159}