<PackageReference Include="Polly.Core" Version="8.3.0" />

RetryHelper

static class RetryHelper
using System; using System.Runtime.CompilerServices; namespace Polly.Retry { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] internal static class RetryHelper { private const double JitterFactor = 0.5; private const double ExponentialFactor = 2; public static bool IsValidDelay(TimeSpan delay) { return delay >= TimeSpan.Zero; } public static TimeSpan GetRetryDelay(DelayBackoffType type, bool jitter, int attempt, TimeSpan baseDelay, TimeSpan? maxDelay, ref double state, Func<double> randomizer) { try { TimeSpan retryDelayCore = GetRetryDelayCore(type, jitter, attempt, baseDelay, ref state, randomizer); if (maxDelay.HasValue) { TimeSpan valueOrDefault = maxDelay.GetValueOrDefault(); if (retryDelayCore > valueOrDefault) return maxDelay.Value; } return retryDelayCore; } catch (OverflowException) { return maxDelay ?? TimeSpan.MaxValue; } } private static TimeSpan GetRetryDelayCore(DelayBackoffType type, bool jitter, int attempt, TimeSpan baseDelay, ref double state, Func<double> randomizer) { if (!(baseDelay == TimeSpan.Zero)) { if (!jitter) { switch (type) { case DelayBackoffType.Constant: return baseDelay; case DelayBackoffType.Linear: return TimeSpan.FromMilliseconds((double)(attempt + 1) * baseDelay.TotalMilliseconds); case DelayBackoffType.Exponential: return TimeSpan.FromMilliseconds(Math.Pow(2, (double)attempt) * baseDelay.TotalMilliseconds); default: throw new ArgumentOutOfRangeException("type", type, "The retry backoff type is not supported."); } } switch (type) { case DelayBackoffType.Constant: return ApplyJitter(baseDelay, randomizer); case DelayBackoffType.Linear: return ApplyJitter(TimeSpan.FromMilliseconds((double)(attempt + 1) * baseDelay.TotalMilliseconds), randomizer); case DelayBackoffType.Exponential: return DecorrelatedJitterBackoffV2(attempt, baseDelay, ref state, randomizer); default: throw new ArgumentOutOfRangeException("type", type, "The retry backoff type is not supported."); } } return baseDelay; } private static TimeSpan DecorrelatedJitterBackoffV2(int attempt, TimeSpan baseDelay, ref double prev, Func<double> randomizer) { double val = (double)TimeSpan.MaxValue.Ticks - 1000; long ticks = baseDelay.Ticks; double num = (double)attempt + randomizer(); double num2 = Math.Pow(2, num) * Math.Tanh(Math.Sqrt(4 * num)); double num3 = num2 - prev; prev = num2; return TimeSpan.FromTicks((long)Math.Min(num3 * 0.7142857142857143 * (double)ticks, val)); } private static TimeSpan ApplyJitter(TimeSpan delay, Func<double> randomizer) { double num = delay.TotalMilliseconds * 0.5 / 2; double num2 = delay.TotalMilliseconds * 0.5 * randomizer() - num; return TimeSpan.FromMilliseconds(delay.TotalMilliseconds + num2); } } }