using StellaOps.Zastava.Observer.Configuration; namespace StellaOps.Zastava.Observer.Worker; internal static class BackoffCalculator { public static TimeSpan ComputeDelay(ObserverBackoffOptions options, int attempt, Random random) { ArgumentNullException.ThrowIfNull(options); ArgumentNullException.ThrowIfNull(random); var cappedAttempt = Math.Max(1, attempt); var baseDelayMs = options.Initial.TotalMilliseconds * Math.Pow(2, cappedAttempt - 1); baseDelayMs = Math.Min(baseDelayMs, options.Max.TotalMilliseconds); if (options.JitterRatio <= 0) { return TimeSpan.FromMilliseconds(baseDelayMs); } var jitterWindow = baseDelayMs * options.JitterRatio; var jitter = (random.NextDouble() * 2 - 1) * jitterWindow; var jittered = Math.Clamp(baseDelayMs + jitter, options.Initial.TotalMilliseconds, options.Max.TotalMilliseconds); return TimeSpan.FromMilliseconds(jittered); } }