public void Backoff_WithFastFirstEqualToTrue_ResultIsZero() { // Arrange var minDelay = TimeSpan.FromMilliseconds(1); var maxDelay = TimeSpan.FromMilliseconds(2); const int retryCount = 3; const bool fastFirst = true; const int seed = 1; // Act IEnumerable <TimeSpan> result = Backoff.AwsDecorrelatedJitterBackoff(minDelay, maxDelay, retryCount, seed, fastFirst); // Assert result.Should().NotBeNull(); result = result.ToList(); result.Should().HaveCount(retryCount); bool first = true; foreach (TimeSpan timeSpan in result) { if (first) { timeSpan.Should().Be(TimeSpan.FromMilliseconds(0)); first = false; } else { timeSpan.Should().BeGreaterOrEqualTo(minDelay); timeSpan.Should().BeLessOrEqualTo(maxDelay); } } }
public void Backoff_WithRetryEqualToZero_ResultIsEmpty() { // Arrange var minDelay = TimeSpan.FromMilliseconds(1); var maxDelay = TimeSpan.FromMilliseconds(2); const int retryCount = 0; const bool fastFirst = false; const int seed = 1; // Act IEnumerable <TimeSpan> result = Backoff.AwsDecorrelatedJitterBackoff(minDelay, maxDelay, retryCount, seed, fastFirst); // Assert result.Should().NotBeNull(); result.Should().BeEmpty(); }
public void Backoff_WithRetryCountLessThanZero_ThrowsException() { // Arrange var minDelay = TimeSpan.FromMilliseconds(1); var maxDelay = TimeSpan.FromMilliseconds(2); const int retryCount = -1; const bool fastFirst = false; const int seed = 1; // Act Action act = () => Backoff.AwsDecorrelatedJitterBackoff(minDelay, maxDelay, retryCount, seed, fastFirst); // Assert act.Should().Throw <ArgumentOutOfRangeException>() .And.ParamName.Should().Be("retryCount"); }
/// <summary> /// This will set up a policy that will retry five times. Each retry will delay for a random /// amount of time between the minimum of 1s and the maximum of 5s. /// </summary> /// <typeparam name="T">The type of response.</typeparam> /// <param name="option">The retry option.</param> /// <param name="context">Request context.</param> /// <param name="action">Action to execute.</param> /// <param name="predicate">Handle result predicate.</param> /// <param name="onRetry">Handle custom on retries.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> /// <remarks> /// Snippet: /// https://github.com/Polly-Contrib/Polly.Contrib.WaitAndRetry/blob/master/src/Polly.Contrib.WaitAndRetry/Backoff.AwsDecorrelatedJitter.cs /// Formula - random(minDelay, min(maxDelay, minDelay * 3))) /// </remarks> public static Task <T> AwsDecorrelatedJitterBackoff <T>( RetryOption option, Context context, Func <Context, Task <T> > action, Func <T, bool> predicate, Action <DelegateResult <T>, TimeSpan, Context> onRetry) { if (option is null) { throw new ArgumentNullException(nameof(option)); } var delay = Backoff.AwsDecorrelatedJitterBackoff( minDelay: TimeSpan.FromMilliseconds(option.MinDelayIsMs), maxDelay: TimeSpan.FromMilliseconds(option.MaxDelayIsMs), retryCount: option.MaxRetry); return(HandleRetry(context, action, predicate, onRetry, delay)); }
public void Backoff_ResultIsInRange(int seed) { // Arrange var minDelay = TimeSpan.FromMilliseconds(10); var maxDelay = TimeSpan.FromMilliseconds(100); const int retryCount = 3; const bool fastFirst = false; // Act IEnumerable <TimeSpan> result = Backoff.AwsDecorrelatedJitterBackoff(minDelay, maxDelay, retryCount, seed, fastFirst); // Assert result.Should().NotBeNull(); result = result.ToList(); result.Should().HaveCount(retryCount); foreach (TimeSpan timeSpan in result) { timeSpan.ShouldBeBetweenOrEqualTo(minDelay, maxDelay); } }