nodedb_types/config/tuning/
startup.rs1use std::time::Duration;
6
7use serde::{Deserialize, Serialize};
8
9pub const DEFAULT_RAFT_READY_TIMEOUT_MS: u64 = 30_000;
11
12pub const DEFAULT_DATA_GROUP_RECOVERY_TIMEOUT_MS: u64 = 60_000;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub struct RaftReadyTimeout(pub Duration);
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26pub struct DataGroupRecoveryTimeout(pub Duration);
27
28impl From<Duration> for RaftReadyTimeout {
29 fn from(value: Duration) -> Self {
30 Self(value)
31 }
32}
33
34impl From<Duration> for DataGroupRecoveryTimeout {
35 fn from(value: Duration) -> Self {
36 Self(value)
37 }
38}
39
40fn default_raft_ready_timeout_ms() -> u64 {
41 DEFAULT_RAFT_READY_TIMEOUT_MS
42}
43
44fn default_data_group_recovery_timeout_ms() -> u64 {
45 DEFAULT_DATA_GROUP_RECOVERY_TIMEOUT_MS
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize)]
54#[serde(deny_unknown_fields)]
55pub struct StartupTuning {
56 #[serde(default = "default_raft_ready_timeout_ms")]
59 pub raft_ready_timeout_ms: u64,
60
61 #[serde(default = "default_data_group_recovery_timeout_ms")]
65 pub data_group_recovery_timeout_ms: u64,
66}
67
68impl Default for StartupTuning {
69 fn default() -> Self {
70 Self {
71 raft_ready_timeout_ms: default_raft_ready_timeout_ms(),
72 data_group_recovery_timeout_ms: default_data_group_recovery_timeout_ms(),
73 }
74 }
75}
76
77impl StartupTuning {
78 pub fn raft_ready_timeout(&self) -> RaftReadyTimeout {
80 RaftReadyTimeout(Duration::from_millis(self.raft_ready_timeout_ms))
81 }
82
83 pub fn data_group_recovery_timeout(&self) -> DataGroupRecoveryTimeout {
85 DataGroupRecoveryTimeout(Duration::from_millis(self.data_group_recovery_timeout_ms))
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn defaults_are_thirty_and_sixty_seconds() {
95 let cfg = StartupTuning::default();
96 assert_eq!(
97 cfg.raft_ready_timeout(),
98 RaftReadyTimeout(Duration::from_secs(30))
99 );
100 assert_eq!(
101 cfg.data_group_recovery_timeout(),
102 DataGroupRecoveryTimeout(Duration::from_secs(60))
103 );
104 }
105
106 #[test]
107 fn one_bound_set_leaves_the_other_at_its_default() {
108 let cfg: StartupTuning =
109 toml::from_str("raft_ready_timeout_ms = 1234").expect("deserialize");
110 assert_eq!(cfg.raft_ready_timeout_ms, 1234);
111 assert_eq!(
112 cfg.data_group_recovery_timeout_ms,
113 DEFAULT_DATA_GROUP_RECOVERY_TIMEOUT_MS
114 );
115 }
116
117 #[test]
118 fn an_unknown_key_is_refused() {
119 let error = toml::from_str::<StartupTuning>("data_group_recovery_timeout = 1800000")
120 .expect_err("a key without the _ms suffix is not a bound");
121 let message = error.to_string();
122 assert!(message.contains("data_group_recovery_timeout"), "{message}");
123 assert!(
124 message.contains("data_group_recovery_timeout_ms"),
125 "the message must list the keys that exist: {message}"
126 );
127 }
128}