prism3_retry/config.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025.
4 * 3-Prism Co. Ltd.
5 *
6 * All rights reserved.
7 *
8 ******************************************************************************/
9//! # Retry Configuration Interface
10//!
11//! Defines the configuration interface for the retry mechanism.
12//!
13//! # Author
14//!
15//! Haixing Hu
16
17use super::delay_strategy::RetryDelayStrategy;
18use std::time::Duration;
19
20/// Retry configuration interface
21///
22/// This interface defines various configuration options for the retry mechanism, supporting flexible retry strategy configuration.
23/// The retry mechanism can be controlled through the following dimensions:
24///
25/// ## Basic Retry Configuration
26/// - **Max Attempts (max_attempts)**: Controls the total number of attempts. Note that the attempt count includes the initial execution,
27/// so retry count = attempt count - 1. For example, setting it to 3 means at most 3 attempts, i.e., at most 2 retries.
28/// - **Max Duration (max_duration)**: Controls the maximum total time for the entire retry process.
29/// Retries will stop after this time, even if the maximum attempt count has not been reached.
30///
31/// ## Delay Strategy Configuration
32/// Explicitly specify the delay strategy to use via the `RetryDelayStrategy` enum, avoiding ambiguity in parameter configuration:
33/// - **Fixed Delay (FIXED)**: Use the same delay time for each retry
34/// - **Random Delay (RANDOM)**: Use a random delay time within the specified range for each retry
35/// - **Exponential Backoff (EXPONENTIAL_BACKOFF)**: Delay time grows exponentially
36///
37/// ## Jitter Configuration
38/// - **Jitter Factor (jitter_factor)**: Relative jitter ratio. Based on the calculated delay time,
39/// randomly add 0 to (delay time × jitter_factor) additional wait time to avoid "thundering herd effect".
40///
41/// # Author
42///
43/// Haixing Hu
44pub trait RetryConfig {
45 // --- Configuration key constants ---
46
47 /// Configuration key for maximum number of attempts
48 const KEY_MAX_ATTEMPTS: &'static str = "retry.max_attempts";
49 /// Configuration key for delay strategy
50 const KEY_DELAY_STRATEGY: &'static str = "retry.delay_strategy";
51 /// Configuration key for fixed delay time
52 const KEY_FIXED_DELAY: &'static str = "retry.fixed_delay_millis";
53 /// Configuration key for random delay minimum value
54 const KEY_RANDOM_MIN_DELAY: &'static str = "retry.random_min_delay_millis";
55 /// Configuration key for random delay maximum value
56 const KEY_RANDOM_MAX_DELAY: &'static str = "retry.random_max_delay_millis";
57 /// Configuration key for exponential backoff initial delay
58 const KEY_BACKOFF_INITIAL_DELAY: &'static str = "retry.backoff_initial_delay_millis";
59 /// Configuration key for exponential backoff maximum delay
60 const KEY_BACKOFF_MAX_DELAY: &'static str = "retry.backoff_max_delay_millis";
61 /// Configuration key for exponential backoff multiplier
62 const KEY_BACKOFF_MULTIPLIER: &'static str = "retry.backoff_multiplier";
63 /// Configuration key for jitter factor
64 const KEY_JITTER_FACTOR: &'static str = "retry.jitter_factor";
65 /// Configuration key for maximum duration of retry execution
66 const KEY_MAX_DURATION: &'static str = "retry.max_duration_millis";
67 /// Configuration key for single operation timeout
68 const KEY_OPERATION_TIMEOUT: &'static str = "retry.operation_timeout_millis";
69
70 // --- Default value constants ---
71
72 /// Default maximum number of attempts for retry mechanism
73 const DEFAULT_MAX_ATTEMPTS: u32 = 5;
74 /// Default delay strategy
75 const DEFAULT_DELAY_STRATEGY: RetryDelayStrategy = RetryDelayStrategy::ExponentialBackoff {
76 initial_delay: Duration::from_millis(1000),
77 max_delay: Duration::from_secs(60),
78 multiplier: 2.0,
79 };
80 /// Default fixed delay time in milliseconds
81 const DEFAULT_FIXED_DELAY_MILLIS: u64 = 1000;
82 /// Default random delay minimum value in milliseconds
83 const DEFAULT_RANDOM_MIN_DELAY_MILLIS: u64 = 1000;
84 /// Default random delay maximum value in milliseconds
85 const DEFAULT_RANDOM_MAX_DELAY_MILLIS: u64 = 10000;
86 /// Default exponential backoff initial delay in milliseconds
87 const DEFAULT_BACKOFF_INITIAL_DELAY_MILLIS: u64 = 1000;
88 /// Default exponential backoff maximum delay in milliseconds
89 const DEFAULT_BACKOFF_MAX_DELAY_MILLIS: u64 = 60000;
90 /// Default exponential backoff multiplier
91 const DEFAULT_BACKOFF_MULTIPLIER: f64 = 2.0;
92 /// Default value for jitter factor
93 const DEFAULT_JITTER_FACTOR: f64 = 0.0;
94 /// Default maximum duration for retry execution in milliseconds, 0 means unlimited
95 const DEFAULT_MAX_DURATION_MILLIS: u64 = 0;
96 /// Default value for single operation timeout in milliseconds, 0 means unlimited
97 const DEFAULT_OPERATION_TIMEOUT_MILLIS: u64 = 0;
98
99 // --- Basic retry control methods ---
100
101 /// Get maximum number of attempts
102 ///
103 /// This property controls the total number of attempts for the operation, including the initial execution and all retries. For example:
104 /// - Set to 1: Execute only once, no retries
105 /// - Set to 3: Execute at most 3 times (initial + at most 2 retries)
106 /// - Set to 5: Execute at most 5 times (initial + at most 4 retries)
107 /// - Note: Actual retry count = max attempts - 1
108 fn max_attempts(&self) -> u32;
109
110 /// Set maximum number of attempts
111 fn set_max_attempts(&mut self, max_attempts: u32) -> &mut Self;
112
113 /// Get maximum duration for retry execution
114 ///
115 /// The maximum duration controls the total time limit for the entire retry process (from initial execution to the last retry).
116 /// When the maximum duration is reached, the retry process will stop regardless of whether the maximum attempt count has been reached.
117 fn max_duration(&self) -> Option<Duration>;
118
119 /// Set maximum duration for retry execution
120 fn set_max_duration(&mut self, max_duration: Option<Duration>) -> &mut Self;
121
122 /// Get single operation timeout
123 ///
124 /// Single operation timeout controls the maximum time for each operation execution. This differs from max_duration:
125 /// - operation_timeout: Maximum execution time for a single operation
126 /// - max_duration: Total time for the entire retry process (including all retries and delays)
127 ///
128 /// Returns None to indicate no single operation timeout limit.
129 fn operation_timeout(&self) -> Option<Duration>;
130
131 /// Set single operation timeout
132 ///
133 /// # Parameters
134 ///
135 /// * `timeout` - Timeout duration, None means unlimited
136 fn set_operation_timeout(&mut self, timeout: Option<Duration>) -> &mut Self;
137
138 // --- Delay strategy methods ---
139
140 /// Get delay strategy type
141 fn delay_strategy(&self) -> RetryDelayStrategy;
142
143 /// Set delay strategy type
144 fn set_delay_strategy(&mut self, delay_strategy: RetryDelayStrategy) -> &mut Self;
145
146 /// Get jitter factor
147 ///
148 /// The jitter factor is a percentage jitter relative to the current delay time. The jitter factor's effective range is [0, delay time × jitterFactor],
149 /// meaning actual delay = calculated delay + random(0, delay time × jitter factor).
150 fn jitter_factor(&self) -> f64;
151
152 /// Set jitter factor
153 fn set_jitter_factor(&mut self, jitter_factor: f64) -> &mut Self;
154
155 // --- Convenience methods ---
156
157 /// Set random delay range
158 ///
159 /// This is a convenience method that sets both the minimum and maximum values for random delay, and sets the delay strategy to random delay.
160 fn set_random_delay_strategy(&mut self, min_delay: Duration, max_delay: Duration) -> &mut Self {
161 self.set_delay_strategy(RetryDelayStrategy::random(min_delay, max_delay));
162 self
163 }
164
165 /// Set fixed delay
166 ///
167 /// This is a convenience method that sets the fixed delay time and sets the delay strategy to fixed delay.
168 fn set_fixed_delay_strategy(&mut self, delay: Duration) -> &mut Self {
169 self.set_delay_strategy(RetryDelayStrategy::fixed(delay));
170 self
171 }
172
173 /// Set exponential backoff strategy parameters
174 ///
175 /// This is a convenience method that sets the initial delay, maximum delay, and multiplier for exponential backoff,
176 /// and sets the delay strategy to exponential backoff.
177 fn set_exponential_backoff_strategy(
178 &mut self,
179 initial_delay: Duration,
180 max_delay: Duration,
181 multiplier: f64,
182 ) -> &mut Self {
183 self.set_delay_strategy(RetryDelayStrategy::exponential_backoff(
184 initial_delay,
185 max_delay,
186 multiplier,
187 ));
188 self
189 }
190
191 /// Set no delay strategy
192 ///
193 /// This is a convenience method that sets the delay strategy to no delay.
194 fn set_no_delay_strategy(&mut self) -> &mut Self {
195 self.set_delay_strategy(RetryDelayStrategy::none());
196 self
197 }
198
199 /// Set unlimited duration
200 ///
201 /// This is a convenience method that sets the maximum duration to None, indicating that the retry process has no time limit,
202 /// and is only controlled by the maximum attempt count.
203 fn set_unlimited_duration(&mut self) -> &mut Self {
204 self.set_max_duration(None);
205 self
206 }
207
208 /// Set unlimited operation timeout
209 ///
210 /// This is a convenience method that sets the single operation timeout to None, indicating that a single operation has no time limit.
211 fn set_unlimited_operation_timeout(&mut self) -> &mut Self {
212 self.set_operation_timeout(None);
213 self
214 }
215}