Skip to main content

forge_core/config/
cluster.rs

1use serde::{Deserialize, Serialize};
2
3/// Cluster configuration.
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct ClusterConfig {
6    /// Cluster name.
7    #[serde(default = "default_cluster_name")]
8    pub name: String,
9
10    /// Discovery method.
11    #[serde(default)]
12    pub discovery: DiscoveryMethod,
13
14    /// Heartbeat interval in seconds.
15    #[serde(default = "default_heartbeat_interval")]
16    pub heartbeat_interval_secs: u64,
17
18    /// Threshold for marking nodes as dead (in seconds).
19    #[serde(default = "default_dead_threshold")]
20    pub dead_threshold_secs: u64,
21
22    /// Static seed nodes (for static discovery).
23    #[serde(default)]
24    pub seed_nodes: Vec<String>,
25
26    /// DNS name for discovery (for DNS discovery).
27    pub dns_name: Option<String>,
28}
29
30impl Default for ClusterConfig {
31    fn default() -> Self {
32        Self {
33            name: default_cluster_name(),
34            discovery: DiscoveryMethod::default(),
35            heartbeat_interval_secs: default_heartbeat_interval(),
36            dead_threshold_secs: default_dead_threshold(),
37            seed_nodes: Vec::new(),
38            dns_name: None,
39        }
40    }
41}
42
43fn default_cluster_name() -> String {
44    "default".to_string()
45}
46
47fn default_heartbeat_interval() -> u64 {
48    5
49}
50
51fn default_dead_threshold() -> u64 {
52    15
53}
54
55/// Cluster discovery method.
56#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
57#[serde(rename_all = "lowercase")]
58pub enum DiscoveryMethod {
59    /// Use PostgreSQL table for discovery.
60    #[default]
61    Postgres,
62
63    /// Use DNS for discovery.
64    Dns,
65
66    /// Use Kubernetes for discovery.
67    Kubernetes,
68
69    /// Use static seed nodes.
70    Static,
71}
72
73#[cfg(test)]
74#[allow(clippy::unwrap_used, clippy::indexing_slicing)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn test_default_cluster_config() {
80        let config = ClusterConfig::default();
81        assert_eq!(config.name, "default");
82        assert_eq!(config.discovery, DiscoveryMethod::Postgres);
83        assert_eq!(config.heartbeat_interval_secs, 5);
84    }
85
86    #[test]
87    fn test_parse_cluster_config() {
88        let toml = r#"
89            name = "production"
90            discovery = "kubernetes"
91            heartbeat_interval_secs = 10
92        "#;
93
94        let config: ClusterConfig = toml::from_str(toml).unwrap();
95        assert_eq!(config.name, "production");
96        assert_eq!(config.discovery, DiscoveryMethod::Kubernetes);
97    }
98}