1use crate::{
2 client::{prepare_command, PreparedCommand},
3 resp::{
4 cmd, CommandArgs, KeyValueArgsCollection, KeyValueCollectionResponse,
5 MultipleArgsCollection, PrimitiveResponse, SingleArg, ToArgs, Value,
6 },
7};
8use serde::Deserialize;
9
10pub trait SentinelCommands<'a> {
14 #[must_use]
19 fn sentinel_config_get<N, RN, RV, R>(self, name: N) -> PreparedCommand<'a, Self, R>
20 where
21 Self: Sized,
22 N: SingleArg,
23 RN: PrimitiveResponse,
24 RV: PrimitiveResponse,
25 R: KeyValueCollectionResponse<RN, RV>,
26 {
27 prepare_command(self, cmd("SENTINEL").arg("CONFIG").arg("GET").arg(name))
28 }
29
30 #[must_use]
32 fn sentinel_config_set<N, V>(self, name: N, value: V) -> PreparedCommand<'a, Self, ()>
33 where
34 Self: Sized,
35 N: SingleArg,
36 V: SingleArg,
37 {
38 prepare_command(
39 self,
40 cmd("SENTINEL")
41 .arg("CONFIG")
42 .arg("SET")
43 .arg(name)
44 .arg(value),
45 )
46 }
47
48 #[must_use]
53 fn sentinel_ckquorum<N>(self, master_name: N) -> PreparedCommand<'a, Self, ()>
54 where
55 Self: Sized,
56 N: SingleArg,
57 {
58 prepare_command(self, cmd("SENTINEL").arg("CKQUORUM").arg(master_name))
59 }
60
61 #[must_use]
66 fn sentinel_failover<N>(self, master_name: N) -> PreparedCommand<'a, Self, ()>
67 where
68 Self: Sized,
69 N: SingleArg,
70 {
71 prepare_command(self, cmd("SENTINEL").arg("FAILOVER").arg(master_name))
72 }
73
74 #[must_use]
83 fn sentinel_flushconfig(self) -> PreparedCommand<'a, Self, ()>
84 where
85 Self: Sized,
86 {
87 prepare_command(self, cmd("SENTINEL").arg("FLUSHCONFIG"))
88 }
89
90 #[must_use]
101 fn sentinel_get_master_addr_by_name<N>(
102 self,
103 master_name: N,
104 ) -> PreparedCommand<'a, Self, Option<(String, u16)>>
105 where
106 Self: Sized,
107 N: SingleArg,
108 {
109 prepare_command(
110 self,
111 cmd("SENTINEL")
112 .arg("GET-MASTER-ADDR-BY-NAME")
113 .arg(master_name),
114 )
115 }
116
117 #[must_use]
119 fn sentinel_info_cache<N, NN, R>(self, master_names: NN) -> PreparedCommand<'a, Self, R>
120 where
121 Self: Sized,
122 N: SingleArg,
123 NN: MultipleArgsCollection<N>,
124 R: KeyValueCollectionResponse<String, Vec<(u64, String)>>,
125 {
126 prepare_command(self, cmd("SENTINEL").arg("INFO-CACHE").arg(master_names))
127 }
128
129 #[must_use]
131 fn sentinel_master<N>(self, master_name: N) -> PreparedCommand<'a, Self, SentinelMasterInfo>
132 where
133 Self: Sized,
134 N: SingleArg,
135 {
136 prepare_command(self, cmd("SENTINEL").arg("MASTER").arg(master_name))
137 }
138
139 #[must_use]
141 fn sentinel_masters(self) -> PreparedCommand<'a, Self, Vec<SentinelMasterInfo>>
142 where
143 Self: Sized,
144 {
145 prepare_command(self, cmd("SENTINEL").arg("MASTERS"))
146 }
147
148 #[must_use]
155 fn sentinel_monitor<N, I>(
156 self,
157 name: N,
158 ip: I,
159 port: u16,
160 quorum: usize,
161 ) -> PreparedCommand<'a, Self, ()>
162 where
163 Self: Sized,
164 N: SingleArg,
165 I: SingleArg,
166 {
167 prepare_command(
168 self,
169 cmd("SENTINEL")
170 .arg("MONITOR")
171 .arg(name)
172 .arg(ip)
173 .arg(port)
174 .arg(quorum),
175 )
176 }
177
178 #[must_use]
184 fn sentinel_remove<N>(self, name: N) -> PreparedCommand<'a, Self, ()>
185 where
186 Self: Sized,
187 N: SingleArg,
188 {
189 prepare_command(self, cmd("SENTINEL").arg("REMOVE").arg(name))
190 }
191
192 #[must_use]
199 fn sentinel_set<N, O, V, C>(self, name: N, configs: C) -> PreparedCommand<'a, Self, ()>
200 where
201 Self: Sized,
202 N: SingleArg,
203 O: SingleArg,
204 V: SingleArg,
205 C: KeyValueArgsCollection<O, V>,
206 {
207 prepare_command(self, cmd("SENTINEL").arg("SET").arg(name).arg(configs))
208 }
209
210 #[must_use]
212 fn sentinel_myid(self) -> PreparedCommand<'a, Self, String>
213 where
214 Self: Sized,
215 {
216 prepare_command(self, cmd("SENTINEL").arg("MYID"))
217 }
218
219 #[must_use]
221 fn sentinel_pending_scripts(self) -> PreparedCommand<'a, Self, Vec<Value>>
222 where
223 Self: Sized,
224 {
225 prepare_command(self, cmd("SENTINEL").arg("PENDING-SCRIPTS"))
226 }
227
228 #[must_use]
230 fn sentinel_replicas<N>(
231 self,
232 master_name: N,
233 ) -> PreparedCommand<'a, Self, Vec<SentinelReplicaInfo>>
234 where
235 Self: Sized,
236 N: SingleArg,
237 {
238 prepare_command(self, cmd("SENTINEL").arg("REPLICAS").arg(master_name))
239 }
240
241 #[must_use]
250 fn sentinel_reset<P>(self, pattern: P) -> PreparedCommand<'a, Self, usize>
251 where
252 Self: Sized,
253 P: SingleArg,
254 {
255 prepare_command(self, cmd("SENTINEL").arg("RESET").arg(pattern))
256 }
257
258 #[must_use]
260 fn sentinel_sentinels<N>(self, master_name: N) -> PreparedCommand<'a, Self, Vec<SentinelInfo>>
261 where
262 Self: Sized,
263 N: SingleArg,
264 {
265 prepare_command(self, cmd("SENTINEL").arg("SENTINELS").arg(master_name))
266 }
267
268 #[must_use]
270 fn sentinel_simulate_failure(
271 self,
272 mode: SentinelSimulateFailureMode,
273 ) -> PreparedCommand<'a, Self, ()>
274 where
275 Self: Sized,
276 {
277 prepare_command(self, cmd("SENTINEL").arg("SIMULATE-FAILURE").arg(mode))
278 }
279}
280
281#[derive(Debug, Deserialize)]
283#[serde(rename_all = "kebab-case")]
284pub struct SentinelMasterInfo {
285 pub name: String,
286 pub ip: String,
287 pub port: u16,
288 pub runid: String,
289 pub flags: String,
290 pub link_pending_commands: usize,
291 pub link_refcount: usize,
292 pub last_ping_sent: usize,
293 pub last_ok_ping_reply: usize,
294 pub last_ping_reply: usize,
295 pub down_after_milliseconds: u64,
296 pub info_refresh: u64,
297 pub role_reported: String,
298 pub role_reported_time: u64,
299 pub config_epoch: usize,
300 pub num_slaves: usize,
301 pub num_other_sentinels: usize,
302 pub quorum: usize,
303 pub failover_timeout: u64,
304 pub parallel_syncs: usize,
305}
306
307#[derive(Debug, Deserialize)]
309#[serde(rename_all = "kebab-case")]
310pub struct SentinelReplicaInfo {
311 pub name: String,
312 pub ip: String,
313 pub port: u16,
314 pub runid: String,
315 pub flags: String,
316 pub link_pending_commands: usize,
317 pub link_refcount: usize,
318 pub last_ping_sent: usize,
319 pub last_ok_ping_reply: usize,
320 pub last_ping_reply: usize,
321 pub down_after_milliseconds: u64,
322 pub info_refresh: u64,
323 pub role_reported: String,
324 pub role_reported_time: u64,
325 pub master_link_down_time: u64,
326 pub master_link_status: String,
327 pub master_host: String,
328 pub master_port: u16,
329 pub slave_priority: u64,
330 pub slave_repl_offset: u64,
331 pub replica_announced: usize,
332}
333
334#[derive(Deserialize)]
336#[serde(rename_all = "kebab-case")]
337pub struct SentinelInfo {
338 pub name: String,
339 pub ip: String,
340 pub port: u16,
341 pub runid: String,
342 pub flags: String,
343 pub link_pending_commands: usize,
344 pub link_refcount: usize,
345 pub last_ping_sent: usize,
346 pub last_ok_ping_reply: usize,
347 pub last_ping_reply: usize,
348 pub down_after_milliseconds: u64,
349 pub last_hello_message: u64,
350 pub voted_leader: String,
351 pub voted_leader_epoch: usize,
352}
353
354pub enum SentinelSimulateFailureMode {
357 CrashAfterElection,
358 CrashAfterPromotion,
359}
360
361impl ToArgs for SentinelSimulateFailureMode {
362 fn write_args(&self, args: &mut CommandArgs) {
363 args.arg(match self {
364 SentinelSimulateFailureMode::CrashAfterElection => "CRASH-AFTER-ELECTION",
365 SentinelSimulateFailureMode::CrashAfterPromotion => "CRASH-AFTER-PROMOTION",
366 });
367 }
368}