reddb_server/replication/
commit_policy.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
28pub enum CommitPolicy {
29 #[default]
30 Local,
31 RemoteWal,
32 AckN(u32),
33 Quorum,
34}
35
36impl CommitPolicy {
37 pub fn label(self) -> &'static str {
38 match self {
39 Self::Local => "local",
40 Self::RemoteWal => "remote_wal",
41 Self::AckN(_) => "ack_n",
42 Self::Quorum => "quorum",
43 }
44 }
45
46 pub fn from_env() -> Self {
50 match std::env::var("RED_PRIMARY_COMMIT_POLICY").ok() {
51 Some(raw) => Self::parse(raw.trim()),
52 None => Self::Local,
53 }
54 }
55
56 pub fn parse(raw: &str) -> Self {
57 let lower = raw.to_ascii_lowercase();
58 if lower == "local" || lower.is_empty() {
59 return Self::Local;
60 }
61 if lower == "remote_wal" {
62 return Self::RemoteWal;
63 }
64 if lower == "quorum" {
65 return Self::Quorum;
66 }
67 if let Some(n_str) = lower.strip_prefix("ack_n=") {
68 if let Ok(n) = n_str.parse::<u32>() {
69 return Self::AckN(n);
70 }
71 }
72 tracing::warn!(
73 target: "reddb::replication::commit_policy",
74 value = %raw,
75 "unknown RED_PRIMARY_COMMIT_POLICY; falling back to local"
76 );
77 Self::Local
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn default_is_local() {
87 assert_eq!(CommitPolicy::default(), CommitPolicy::Local);
88 }
89
90 #[test]
91 fn parse_known_values() {
92 assert_eq!(CommitPolicy::parse("local"), CommitPolicy::Local);
93 assert_eq!(CommitPolicy::parse("LOCAL"), CommitPolicy::Local);
94 assert_eq!(CommitPolicy::parse("remote_wal"), CommitPolicy::RemoteWal);
95 assert_eq!(CommitPolicy::parse("quorum"), CommitPolicy::Quorum);
96 assert_eq!(CommitPolicy::parse("ack_n=3"), CommitPolicy::AckN(3));
97 assert_eq!(CommitPolicy::parse("ack_n=0"), CommitPolicy::AckN(0));
98 }
99
100 #[test]
101 fn parse_unknown_falls_back_to_local() {
102 assert_eq!(CommitPolicy::parse("nonsense"), CommitPolicy::Local);
103 assert_eq!(CommitPolicy::parse("ack_n=abc"), CommitPolicy::Local);
104 assert_eq!(CommitPolicy::parse(""), CommitPolicy::Local);
105 }
106
107 #[test]
108 fn label_round_trips_known_values() {
109 assert_eq!(CommitPolicy::Local.label(), "local");
110 assert_eq!(CommitPolicy::RemoteWal.label(), "remote_wal");
111 assert_eq!(CommitPolicy::AckN(5).label(), "ack_n");
112 assert_eq!(CommitPolicy::Quorum.label(), "quorum");
113 }
114}