prism3_retry/
default_config.rs1use super::config::RetryConfig;
18use super::delay_strategy::RetryDelayStrategy;
19use prism3_config::{Config, Configurable};
20use std::time::Duration;
21
22#[derive(Debug, Clone)]
30pub struct DefaultRetryConfig {
31 config: Config,
32}
33
34impl DefaultRetryConfig {
35 pub fn new() -> Self {
37 Self {
38 config: Config::new(),
39 }
40 }
41
42 pub fn with_config(config: Config) -> Self {
44 Self { config }
45 }
46
47 fn get_delay_strategy_from_config(&self) -> RetryDelayStrategy {
49 let strategy_name = self
50 .config
51 .get_string_or(Self::KEY_DELAY_STRATEGY, "EXPONENTIAL_BACKOFF");
52
53 match strategy_name.as_str() {
54 "NONE" => RetryDelayStrategy::none(),
55 "FIXED" => {
56 let delay_millis = self
57 .config
58 .get_or(Self::KEY_FIXED_DELAY, Self::DEFAULT_FIXED_DELAY_MILLIS);
59 RetryDelayStrategy::fixed(Duration::from_millis(delay_millis))
60 }
61 "RANDOM" => {
62 let min_delay_millis = self.config.get_or(
63 Self::KEY_RANDOM_MIN_DELAY,
64 Self::DEFAULT_RANDOM_MIN_DELAY_MILLIS,
65 );
66 let max_delay_millis = self.config.get_or(
67 Self::KEY_RANDOM_MAX_DELAY,
68 Self::DEFAULT_RANDOM_MAX_DELAY_MILLIS,
69 );
70 RetryDelayStrategy::random(
71 Duration::from_millis(min_delay_millis),
72 Duration::from_millis(max_delay_millis),
73 )
74 }
75 "EXPONENTIAL_BACKOFF" => {
76 let initial_delay_millis = self.config.get_or(
77 Self::KEY_BACKOFF_INITIAL_DELAY,
78 Self::DEFAULT_BACKOFF_INITIAL_DELAY_MILLIS,
79 );
80 let max_delay_millis = self.config.get_or(
81 Self::KEY_BACKOFF_MAX_DELAY,
82 Self::DEFAULT_BACKOFF_MAX_DELAY_MILLIS,
83 );
84 let multiplier = self.config.get_or(
85 Self::KEY_BACKOFF_MULTIPLIER,
86 Self::DEFAULT_BACKOFF_MULTIPLIER,
87 );
88 RetryDelayStrategy::exponential_backoff(
89 Duration::from_millis(initial_delay_millis),
90 Duration::from_millis(max_delay_millis),
91 multiplier,
92 )
93 }
94 _ => Self::DEFAULT_DELAY_STRATEGY,
95 }
96 }
97
98 fn set_delay_strategy_to_config(&mut self, strategy: &RetryDelayStrategy) {
100 match strategy {
101 RetryDelayStrategy::None => {
102 self.config.set(Self::KEY_DELAY_STRATEGY, "NONE").unwrap();
103 }
104 RetryDelayStrategy::Fixed { delay } => {
105 self.config.set(Self::KEY_DELAY_STRATEGY, "FIXED").unwrap();
106 self.config
107 .set(Self::KEY_FIXED_DELAY, delay.as_millis() as u64)
108 .unwrap();
109 }
110 RetryDelayStrategy::Random {
111 min_delay,
112 max_delay,
113 } => {
114 self.config.set(Self::KEY_DELAY_STRATEGY, "RANDOM").unwrap();
115 self.config
116 .set(Self::KEY_RANDOM_MIN_DELAY, min_delay.as_millis() as u64)
117 .unwrap();
118 self.config
119 .set(Self::KEY_RANDOM_MAX_DELAY, max_delay.as_millis() as u64)
120 .unwrap();
121 }
122 RetryDelayStrategy::ExponentialBackoff {
123 initial_delay,
124 max_delay,
125 multiplier,
126 } => {
127 self.config
128 .set(Self::KEY_DELAY_STRATEGY, "EXPONENTIAL_BACKOFF")
129 .unwrap();
130 self.config
131 .set(
132 Self::KEY_BACKOFF_INITIAL_DELAY,
133 initial_delay.as_millis() as u64,
134 )
135 .unwrap();
136 self.config
137 .set(Self::KEY_BACKOFF_MAX_DELAY, max_delay.as_millis() as u64)
138 .unwrap();
139 self.config
140 .set(Self::KEY_BACKOFF_MULTIPLIER, *multiplier)
141 .unwrap();
142 }
143 }
144 }
145}
146
147impl Default for DefaultRetryConfig {
148 fn default() -> Self {
149 Self::new()
150 }
151}
152
153impl Configurable for DefaultRetryConfig {
154 fn config(&self) -> &Config {
155 &self.config
156 }
157
158 fn config_mut(&mut self) -> &mut Config {
159 &mut self.config
160 }
161
162 fn set_config(&mut self, config: Config) {
163 self.config = config;
164 self.on_config_changed();
165 }
166
167 fn on_config_changed(&mut self) {
168 }
170}
171
172impl RetryConfig for DefaultRetryConfig {
173 fn max_attempts(&self) -> u32 {
174 self.config
175 .get_or(Self::KEY_MAX_ATTEMPTS, Self::DEFAULT_MAX_ATTEMPTS)
176 }
177
178 fn set_max_attempts(&mut self, max_attempts: u32) -> &mut Self {
179 self.config
180 .set(Self::KEY_MAX_ATTEMPTS, max_attempts)
181 .unwrap();
182 self
183 }
184
185 fn max_duration(&self) -> Option<Duration> {
186 let millis = self
187 .config
188 .get_or(Self::KEY_MAX_DURATION, Self::DEFAULT_MAX_DURATION_MILLIS);
189 if millis == 0 {
190 None
191 } else {
192 Some(Duration::from_millis(millis))
193 }
194 }
195
196 fn set_max_duration(&mut self, max_duration: Option<Duration>) -> &mut Self {
197 match max_duration {
198 None => self.config.set(Self::KEY_MAX_DURATION, 0u64).unwrap(),
199 Some(duration) => self
200 .config
201 .set(Self::KEY_MAX_DURATION, duration.as_millis() as u64)
202 .unwrap(),
203 }
204 self
205 }
206
207 fn operation_timeout(&self) -> Option<Duration> {
208 let millis = self.config.get_or(
209 Self::KEY_OPERATION_TIMEOUT,
210 Self::DEFAULT_OPERATION_TIMEOUT_MILLIS,
211 );
212 if millis == 0 {
213 None
214 } else {
215 Some(Duration::from_millis(millis))
216 }
217 }
218
219 fn set_operation_timeout(&mut self, timeout: Option<Duration>) -> &mut Self {
220 match timeout {
221 None => self.config.set(Self::KEY_OPERATION_TIMEOUT, 0u64).unwrap(),
222 Some(duration) => self
223 .config
224 .set(Self::KEY_OPERATION_TIMEOUT, duration.as_millis() as u64)
225 .unwrap(),
226 }
227 self
228 }
229
230 fn delay_strategy(&self) -> RetryDelayStrategy {
231 self.get_delay_strategy_from_config()
232 }
233
234 fn set_delay_strategy(&mut self, delay_strategy: RetryDelayStrategy) -> &mut Self {
235 self.set_delay_strategy_to_config(&delay_strategy);
236 self
237 }
238
239 fn jitter_factor(&self) -> f64 {
240 self.config
241 .get_or(Self::KEY_JITTER_FACTOR, Self::DEFAULT_JITTER_FACTOR)
242 }
243
244 fn set_jitter_factor(&mut self, jitter_factor: f64) -> &mut Self {
245 self.config
246 .set(Self::KEY_JITTER_FACTOR, jitter_factor)
247 .unwrap();
248 self
249 }
250}