noxu_rep/
commit_durability.rs1use std::time::Duration;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
12pub enum ReplicaAckPolicy {
13 All,
15
16 #[default]
19 SimpleMajority,
20
21 None,
24}
25
26impl ReplicaAckPolicy {
27 pub fn required_acks(&self, electable_count: u32) -> u32 {
35 match self {
36 ReplicaAckPolicy::All => {
37 if electable_count == 0 {
38 0
39 } else {
40 electable_count - 1
41 }
42 }
43 ReplicaAckPolicy::SimpleMajority => {
44 if electable_count <= 1 {
45 0
46 } else {
47 let majority = electable_count / 2 + 1;
49 majority - 1
50 }
51 }
52 ReplicaAckPolicy::None => 0,
53 }
54 }
55}
56
57impl std::fmt::Display for ReplicaAckPolicy {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 match self {
60 ReplicaAckPolicy::All => write!(f, "ALL"),
61 ReplicaAckPolicy::SimpleMajority => write!(f, "SIMPLE_MAJORITY"),
62 ReplicaAckPolicy::None => write!(f, "NONE"),
63 }
64 }
65}
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
72pub struct CommitDurability {
73 pub ack_policy: ReplicaAckPolicy,
75 pub ack_timeout: Duration,
77}
78
79impl CommitDurability {
80 pub fn new(ack_policy: ReplicaAckPolicy, ack_timeout: Duration) -> Self {
82 Self { ack_policy, ack_timeout }
83 }
84
85 pub fn required_acks(&self, electable_count: u32) -> u32 {
88 self.ack_policy.required_acks(electable_count)
89 }
90}
91
92impl Default for CommitDurability {
93 fn default() -> Self {
94 Self {
95 ack_policy: ReplicaAckPolicy::default(),
96 ack_timeout: Duration::from_secs(5),
97 }
98 }
99}
100
101impl std::fmt::Display for CommitDurability {
102 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
103 write!(
104 f,
105 "CommitDurability(ack_policy={}, ack_timeout={:?})",
106 self.ack_policy, self.ack_timeout
107 )
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114
115 #[test]
118 fn test_all_required_acks() {
119 assert_eq!(ReplicaAckPolicy::All.required_acks(0), 0);
120 assert_eq!(ReplicaAckPolicy::All.required_acks(1), 0);
121 assert_eq!(ReplicaAckPolicy::All.required_acks(2), 1);
122 assert_eq!(ReplicaAckPolicy::All.required_acks(3), 2);
123 assert_eq!(ReplicaAckPolicy::All.required_acks(5), 4);
124 }
125
126 #[test]
127 fn test_simple_majority_required_acks() {
128 assert_eq!(ReplicaAckPolicy::SimpleMajority.required_acks(0), 0);
129 assert_eq!(ReplicaAckPolicy::SimpleMajority.required_acks(1), 0);
130 assert_eq!(ReplicaAckPolicy::SimpleMajority.required_acks(2), 1);
132 assert_eq!(ReplicaAckPolicy::SimpleMajority.required_acks(3), 1);
134 assert_eq!(ReplicaAckPolicy::SimpleMajority.required_acks(4), 2);
136 assert_eq!(ReplicaAckPolicy::SimpleMajority.required_acks(5), 2);
138 }
139
140 #[test]
141 fn test_none_required_acks() {
142 assert_eq!(ReplicaAckPolicy::None.required_acks(0), 0);
143 assert_eq!(ReplicaAckPolicy::None.required_acks(1), 0);
144 assert_eq!(ReplicaAckPolicy::None.required_acks(5), 0);
145 assert_eq!(ReplicaAckPolicy::None.required_acks(100), 0);
146 }
147
148 #[test]
149 fn test_ack_policy_display() {
150 assert_eq!(ReplicaAckPolicy::All.to_string(), "ALL");
151 assert_eq!(
152 ReplicaAckPolicy::SimpleMajority.to_string(),
153 "SIMPLE_MAJORITY"
154 );
155 assert_eq!(ReplicaAckPolicy::None.to_string(), "NONE");
156 }
157
158 #[test]
159 fn test_ack_policy_default() {
160 assert_eq!(
161 ReplicaAckPolicy::default(),
162 ReplicaAckPolicy::SimpleMajority
163 );
164 }
165
166 #[test]
167 fn test_ack_policy_clone_copy_eq_hash() {
168 use std::collections::HashSet;
169 let p = ReplicaAckPolicy::All;
170 let p2 = p;
171 assert_eq!(p, p2);
172 let mut set = HashSet::new();
173 set.insert(ReplicaAckPolicy::All);
174 set.insert(ReplicaAckPolicy::SimpleMajority);
175 set.insert(ReplicaAckPolicy::None);
176 assert_eq!(set.len(), 3);
177 }
178
179 #[test]
182 fn test_commit_durability_new() {
183 let cd = CommitDurability::new(
184 ReplicaAckPolicy::All,
185 Duration::from_secs(10),
186 );
187 assert_eq!(cd.ack_policy, ReplicaAckPolicy::All);
188 assert_eq!(cd.ack_timeout, Duration::from_secs(10));
189 }
190
191 #[test]
192 fn test_commit_durability_required_acks() {
193 let cd = CommitDurability::new(
194 ReplicaAckPolicy::SimpleMajority,
195 Duration::from_secs(5),
196 );
197 assert_eq!(cd.required_acks(3), 1);
198 assert_eq!(cd.required_acks(5), 2);
199 }
200
201 #[test]
202 fn test_commit_durability_default() {
203 let cd = CommitDurability::default();
204 assert_eq!(cd.ack_policy, ReplicaAckPolicy::SimpleMajority);
205 assert_eq!(cd.ack_timeout, Duration::from_secs(5));
206 }
207
208 #[test]
209 fn test_commit_durability_display() {
210 let cd = CommitDurability::default();
211 let s = cd.to_string();
212 assert!(s.contains("SIMPLE_MAJORITY"));
213 assert!(s.contains("5s"));
214 }
215
216 #[test]
217 fn test_commit_durability_clone_eq() {
218 let cd = CommitDurability::default();
219 let cloned = cd;
220 assert_eq!(cd, cloned);
221 }
222}