opencode_orchestrator_mcp/
config.rs1use std::time::Duration;
2
3pub const OPENCODE_ORCHESTRATOR_IDLE_GRACE_MS: &str = "OPENCODE_ORCHESTRATOR_IDLE_GRACE_MS";
4const DEFAULT_IDLE_GRACE_MS: u64 = 1000;
5
6pub fn idle_grace() -> Duration {
7 match std::env::var(OPENCODE_ORCHESTRATOR_IDLE_GRACE_MS) {
8 Ok(value) if !value.trim().is_empty() => {
9 if let Ok(ms) = value.trim().parse::<u64>() {
10 Duration::from_millis(ms)
11 } else {
12 tracing::warn!(
13 value = %value,
14 "invalid OPENCODE_ORCHESTRATOR_IDLE_GRACE_MS; using default"
15 );
16 Duration::from_millis(DEFAULT_IDLE_GRACE_MS)
17 }
18 }
19 _ => Duration::from_millis(DEFAULT_IDLE_GRACE_MS),
20 }
21}
22
23#[cfg(test)]
24mod tests {
25 use super::*;
26 use serial_test::serial;
27
28 #[test]
29 #[serial(env)]
30 fn idle_grace_uses_default_when_env_missing() {
31 unsafe { std::env::remove_var(OPENCODE_ORCHESTRATOR_IDLE_GRACE_MS) };
33 assert_eq!(idle_grace(), Duration::from_millis(DEFAULT_IDLE_GRACE_MS));
34 }
35
36 #[test]
37 #[serial(env)]
38 fn idle_grace_uses_env_value_when_valid() {
39 unsafe { std::env::set_var(OPENCODE_ORCHESTRATOR_IDLE_GRACE_MS, "42") };
41 assert_eq!(idle_grace(), Duration::from_millis(42));
42 unsafe { std::env::remove_var(OPENCODE_ORCHESTRATOR_IDLE_GRACE_MS) };
44 }
45
46 #[test]
47 #[serial(env)]
48 fn idle_grace_falls_back_when_env_invalid() {
49 unsafe { std::env::set_var(OPENCODE_ORCHESTRATOR_IDLE_GRACE_MS, "abc") };
51 assert_eq!(idle_grace(), Duration::from_millis(DEFAULT_IDLE_GRACE_MS));
52 unsafe { std::env::remove_var(OPENCODE_ORCHESTRATOR_IDLE_GRACE_MS) };
54 }
55
56 #[test]
57 #[serial(env)]
58 fn idle_grace_falls_back_when_env_empty() {
59 unsafe { std::env::set_var(OPENCODE_ORCHESTRATOR_IDLE_GRACE_MS, " ") };
61 assert_eq!(idle_grace(), Duration::from_millis(DEFAULT_IDLE_GRACE_MS));
62 unsafe { std::env::remove_var(OPENCODE_ORCHESTRATOR_IDLE_GRACE_MS) };
64 }
65}