namespace MoShiro.Agent; /// /// QUIC 数据通道的重拨节奏:1、2、3、5 秒,之后固定 5 秒。数据通道断开期间的测量是缺口,所以不像控制连接那样拉长到一分钟。 /// 抖动由调用方通过 给出,避免多条线路同时重拨。 /// public sealed class QuicRedialBackoff { private static readonly TimeSpan[] s_delays = [TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(5)]; private const int ShortAttempts = 12; private int _attempt; public int Attempts => _attempt; public TimeSpan Next(Random? random = null) { TimeSpan delay = s_delays[Math.Min(_attempt, s_delays.Length - 1)]; if (_attempt >= ShortAttempts) { // 短间隔已经连续失败了这么多次:这条路径大概率是死的(对端不通、被丢弃),握手和日志都是白费,翻倍退避,最长五分钟 delay = TimeSpan.FromSeconds(Math.Min(300, 5 * (1 << Math.Min(_attempt - ShortAttempts + 1, 6)))); } _attempt++; return random is null ? delay : delay * (0.8 + (0.4 * random.NextDouble())); } public void Reset() => _attempt = 0; }