From 5a0963665d7b1fad5ab13c6507be4cb531c66830 Mon Sep 17 00:00:00 2001 From: Anders Olsson Date: Mon, 25 May 2026 11:22:52 +0200 Subject: [PATCH] feat(protocol): RestartPolicy/RestartConfig/StopConfig with defaults --- crates/xy-protocol/src/config.rs | 88 ++++++++++++++++++++++++++++++++ crates/xy-protocol/src/lib.rs | 2 + 2 files changed, 90 insertions(+) create mode 100644 crates/xy-protocol/src/config.rs diff --git a/crates/xy-protocol/src/config.rs b/crates/xy-protocol/src/config.rs new file mode 100644 index 0000000..f520339 --- /dev/null +++ b/crates/xy-protocol/src/config.rs @@ -0,0 +1,88 @@ +use serde::{Deserialize, Serialize}; +use std::time::Duration; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub enum RestartPolicy { + Always, + OnFailure, + Never, +} + +impl Default for RestartPolicy { + fn default() -> Self { + RestartPolicy::OnFailure + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct RestartConfig { + #[serde(default)] + pub policy: RestartPolicy, + #[serde(default = "default_backoff_initial", with = "humantime_serde")] + pub backoff_initial: Duration, + #[serde(default = "default_backoff_max", with = "humantime_serde")] + pub backoff_max: Duration, + #[serde(default = "default_max_retries_per_minute")] + pub max_retries_per_minute: u32, +} + +fn default_backoff_initial() -> Duration { + Duration::from_secs(1) +} + +fn default_backoff_max() -> Duration { + Duration::from_secs(30) +} + +fn default_max_retries_per_minute() -> u32 { + 5 +} + +impl Default for RestartConfig { + fn default() -> Self { + Self { + policy: RestartPolicy::default(), + backoff_initial: default_backoff_initial(), + backoff_max: default_backoff_max(), + max_retries_per_minute: default_max_retries_per_minute(), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct StopConfig { + #[serde(default = "default_grace", with = "humantime_serde")] + pub grace: Duration, +} + +fn default_grace() -> Duration { + Duration::from_secs(10) +} + +impl Default for StopConfig { + fn default() -> Self { + Self { + grace: default_grace(), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn restart_config_defaults() { + let c = RestartConfig::default(); + assert_eq!(c.policy, RestartPolicy::OnFailure); + assert_eq!(c.backoff_initial, Duration::from_secs(1)); + assert_eq!(c.backoff_max, Duration::from_secs(30)); + assert_eq!(c.max_retries_per_minute, 5); + } + + #[test] + fn stop_config_defaults() { + assert_eq!(StopConfig::default().grace, Duration::from_secs(10)); + } +} diff --git a/crates/xy-protocol/src/lib.rs b/crates/xy-protocol/src/lib.rs index 33f24e9..246cdfd 100644 --- a/crates/xy-protocol/src/lib.rs +++ b/crates/xy-protocol/src/lib.rs @@ -1,5 +1,7 @@ //! Wire types and config schema shared between the xy daemon and CLI. +pub mod config; pub mod state; +pub use config::{RestartConfig, RestartPolicy, StopConfig}; pub use state::ServerState;