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)]
74mod tests {
75    use super::*;
76
77    #[test]
78    fn test_default_cluster_config() {
79        let config = ClusterConfig::default();
80        assert_eq!(config.name, "default");
81        assert_eq!(config.discovery, DiscoveryMethod::Postgres);
82        assert_eq!(config.heartbeat_interval_secs, 5);
83    }
84
85    #[test]
86    fn test_parse_cluster_config() {
87        let toml = r#"
88            name = "production"
89            discovery = "kubernetes"
90            heartbeat_interval_secs = 10
91        "#;
92
93        let config: ClusterConfig = toml::from_str(toml).unwrap();
94        assert_eq!(config.name, "production");
95        assert_eq!(config.discovery, DiscoveryMethod::Kubernetes);
96    }
97}