forge_core/cluster/
roles.rs1use std::str::FromStr;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub enum NodeRole {
6 Gateway,
8 Function,
10 Worker,
12 Scheduler,
14}
15
16impl NodeRole {
17 pub fn as_str(&self) -> &'static str {
19 match self {
20 Self::Gateway => "gateway",
21 Self::Function => "function",
22 Self::Worker => "worker",
23 Self::Scheduler => "scheduler",
24 }
25 }
26
27 pub fn all() -> Vec<Self> {
29 vec![Self::Gateway, Self::Function, Self::Worker, Self::Scheduler]
30 }
31}
32
33#[derive(Debug, Clone, PartialEq, Eq)]
35pub struct ParseNodeRoleError(pub String);
36
37impl std::fmt::Display for ParseNodeRoleError {
38 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39 write!(f, "invalid node role: {}", self.0)
40 }
41}
42
43impl std::error::Error for ParseNodeRoleError {}
44
45impl FromStr for NodeRole {
46 type Err = ParseNodeRoleError;
47
48 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
49 match s {
50 "gateway" => Ok(Self::Gateway),
51 "function" => Ok(Self::Function),
52 "worker" => Ok(Self::Worker),
53 "scheduler" => Ok(Self::Scheduler),
54 _ => Err(ParseNodeRoleError(s.to_string())),
55 }
56 }
57}
58
59impl std::fmt::Display for NodeRole {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 write!(f, "{}", self.as_str())
62 }
63}
64
65#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
67pub enum LeaderRole {
68 Scheduler,
70 MetricsAggregator,
72 LogCompactor,
74}
75
76impl LeaderRole {
77 pub fn lock_id(&self) -> i64 {
79 match self {
82 Self::Scheduler => 0x464F_5247_0001,
83 Self::MetricsAggregator => 0x464F_5247_0002,
84 Self::LogCompactor => 0x464F_5247_0003,
85 }
86 }
87
88 pub fn as_str(&self) -> &'static str {
90 match self {
91 Self::Scheduler => "scheduler",
92 Self::MetricsAggregator => "metrics_aggregator",
93 Self::LogCompactor => "log_compactor",
94 }
95 }
96}
97
98#[derive(Debug, Clone, PartialEq, Eq)]
100pub struct ParseLeaderRoleError(pub String);
101
102impl std::fmt::Display for ParseLeaderRoleError {
103 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104 write!(f, "invalid leader role: {}", self.0)
105 }
106}
107
108impl std::error::Error for ParseLeaderRoleError {}
109
110impl FromStr for LeaderRole {
111 type Err = ParseLeaderRoleError;
112
113 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
114 match s {
115 "scheduler" => Ok(Self::Scheduler),
116 "metrics_aggregator" => Ok(Self::MetricsAggregator),
117 "log_compactor" => Ok(Self::LogCompactor),
118 _ => Err(ParseLeaderRoleError(s.to_string())),
119 }
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126
127 #[test]
128 fn test_node_role_conversion() {
129 assert_eq!("gateway".parse::<NodeRole>(), Ok(NodeRole::Gateway));
130 assert_eq!("worker".parse::<NodeRole>(), Ok(NodeRole::Worker));
131 assert!("invalid".parse::<NodeRole>().is_err());
132 assert_eq!(NodeRole::Gateway.as_str(), "gateway");
133 }
134
135 #[test]
136 fn test_all_roles() {
137 let roles = NodeRole::all();
138 assert_eq!(roles.len(), 4);
139 assert!(roles.contains(&NodeRole::Gateway));
140 assert!(roles.contains(&NodeRole::Scheduler));
141 }
142
143 #[test]
144 fn test_leader_role_lock_ids() {
145 let scheduler_id = LeaderRole::Scheduler.lock_id();
147 let metrics_id = LeaderRole::MetricsAggregator.lock_id();
148 let log_id = LeaderRole::LogCompactor.lock_id();
149
150 assert_ne!(scheduler_id, metrics_id);
151 assert_ne!(metrics_id, log_id);
152 assert_ne!(scheduler_id, log_id);
153 }
154
155 #[test]
156 fn test_leader_role_conversion() {
157 assert_eq!("scheduler".parse::<LeaderRole>(), Ok(LeaderRole::Scheduler));
158 assert!("invalid".parse::<LeaderRole>().is_err());
159 assert_eq!(LeaderRole::Scheduler.as_str(), "scheduler");
160 }
161}