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}