Innovenergy_trunk/csharp/Lib/Utils/Try/Operators.async.cs

79 lines
2.0 KiB
C#
Raw Normal View History

2023-02-16 12:57:06 +00:00
namespace InnovEnergy.Lib.Utils.Try;
public partial class TryAsync<R>
{
public TryAsync<R> Retry(Int32 nTimes)
{
return Retry<Exception>(nTimes);
}
public TryAsync<R> Retry<E>(Int32 nTimes) where E:Exception
{
Task<Boolean> ShouldRetry(E _) => Task.FromResult(nTimes-- > 0);
return Retry<E>(ShouldRetry);
}
public TryAsync<R> ExponentialBackoff(TimeSpan initialDelay,
Int32 nAttempts,
Double jitterRatio = 0.1)
{
Boolean YesToAll(Exception _) => true;
return ExponentialBackoff<Exception>(YesToAll, initialDelay, nAttempts, jitterRatio);
}
public TryAsync<R> ExponentialBackoff<E>(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<Boolean> ShouldRetry(E exception)
{
if (nAttempts-- > 0)
{
delay = delay.ApplyJitter(jitterRatio);
await Task.Delay(delay);
delay *= 2;
return true;
}
return false;
}
return Retry<E>(ShouldRetry);
}
public TryAsync<R> ExponentialBackoff<E>(Func<E, Boolean> 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<Boolean> ShouldRetry(E exception)
{
if (nAttempts-- > 0 && shouldRetry(exception))
{
delay = delay.ApplyJitter(jitterRatio);
await Task.Delay(delay);
delay *= 2;
return true;
}
return false;
}
return Retry<E>(ShouldRetry);
}
}