namespace InnovEnergy.Lib.Utils.Try; public partial class TryAsync { public TryAsync Retry(Int32 nTimes) { return Retry(nTimes); } public TryAsync Retry(Int32 nTimes) where E:Exception { Task ShouldRetry(E _) => Task.FromResult(nTimes-- > 0); return Retry(ShouldRetry); } public TryAsync ExponentialBackoff(TimeSpan initialDelay, Int32 nAttempts, Double jitterRatio = 0.1) { Boolean YesToAll(Exception _) => true; return ExponentialBackoff(YesToAll, initialDelay, nAttempts, jitterRatio); } public TryAsync ExponentialBackoff(TimeSpan initialDelay, Int32 nAttempts, Double jitterRatio = 0.1) where E : Exception { if (jitterRatio is < 0 or > 1) throw new ArgumentException(nameof(jitterRatio)); var delay = initialDelay; async Task ShouldRetry(E exception) { if (nAttempts-- > 0) { delay = delay.ApplyJitter(jitterRatio); await Task.Delay(delay); delay *= 2; return true; } return false; } return Retry(ShouldRetry); } public TryAsync ExponentialBackoff(Func shouldRetry, TimeSpan initialDelay, Int32 nAttempts, Double jitterRatio = 0.1) where E : Exception { if (jitterRatio is < 0 or > 1) throw new ArgumentException(nameof(jitterRatio)); var delay = initialDelay; async Task ShouldRetry(E exception) { if (nAttempts-- > 0 && shouldRetry(exception)) { delay = delay.ApplyJitter(jitterRatio); await Task.Delay(delay); delay *= 2; return true; } return false; } return Retry(ShouldRetry); } }