Skip to main content

futu_net/
reconnect.rs

1use std::time::Duration;
2
3/// 重连策略:指数退避
4///
5/// 每次重连失败后,等待时间翻倍,直到达到最大等待时间。
6/// 成功连接后重置。
7#[derive(Debug, Clone)]
8pub struct ReconnectPolicy {
9    base_delay: Duration,
10    max_delay: Duration,
11    max_retries: Option<u32>,
12    current_attempt: u32,
13}
14
15impl ReconnectPolicy {
16    /// 创建新的重连策略
17    ///
18    /// - `base_delay`: 首次重连等待时间
19    /// - `max_delay`: 最大等待时间上限
20    /// - `max_retries`: 最大重试次数,None 表示无限重试
21    pub fn new(base_delay: Duration, max_delay: Duration, max_retries: Option<u32>) -> Self {
22        Self {
23            base_delay,
24            max_delay,
25            max_retries,
26            current_attempt: 0,
27        }
28    }
29
30    /// 默认策略:1秒起始,30秒上限,无限重试
31    pub fn default_policy() -> Self {
32        Self::new(Duration::from_secs(1), Duration::from_secs(30), None)
33    }
34
35    /// 获取下一次重连的等待时间
36    ///
37    /// 返回 None 表示已达到最大重试次数,应停止重连。
38    pub fn next_delay(&mut self) -> Option<Duration> {
39        if let Some(max) = self.max_retries
40            && self.current_attempt >= max
41        {
42            return None;
43        }
44
45        let multiplier = 1u32.checked_shl(self.current_attempt).unwrap_or(u32::MAX);
46        let delay = self.base_delay.saturating_mul(multiplier);
47        let delay = delay.min(self.max_delay);
48
49        self.current_attempt += 1;
50
51        Some(delay)
52    }
53
54    /// 重置重连计数(连接成功后调用)
55    pub fn reset(&mut self) {
56        self.current_attempt = 0;
57    }
58
59    /// 当前已重试次数
60    pub fn attempts(&self) -> u32 {
61        self.current_attempt
62    }
63}
64
65#[cfg(test)]
66mod tests;