public async Task ExponentialBackoffTestShouldThrowTooManyRetriesAsync() { var subject = new ExponentialBackoff(1, 1, 2); await subject.DelayAsync().ConfigureAwait(false); await Assert.ThrowsExceptionAsync <TooManyRetryAttemptsException>(async() => await subject.DelayAsync().ConfigureAwait(false)).ConfigureAwait(false); }
public void ExponentialBackoffTestShouldProgressExponentially() { const int maxDelay = 500000; var maxLog = (int)Math.Ceiling(Math.Log(maxDelay, 2)); var subject = new ExponentialBackoff(20, 1, maxDelay); for (var i = 0; i < maxLog; i++) { Assert.AreEqual(TimeSpan.FromMilliseconds(Math.Pow(2, i)), subject.GetDelay(i)); } for (var i = maxLog; i < 5000; i++) { Assert.AreEqual(TimeSpan.FromMilliseconds(maxDelay), subject.GetDelay(i)); } }
/// <summary> /// RunAsync will attempt to execute the a task with a exponential retry /// </summary> /// <param name="func">task to execute</param> /// <returns>exponentially backed off task</returns> public async Task RunAsync(Func <Task> func) { var backoff = new ExponentialBackoff(_maxRetries, _delayMilliseconds, _maxDelayMilliseconds); retry: try { await func().ConfigureAwait(false); } catch (Exception ex) when(ex is TimeoutException || ex is HttpRequestException || ex is TaskCanceledException || ex is OperationCanceledException || ex is TransientManagedIdentityException) { Debug.WriteLine(ex.ToString()); await backoff.DelayAsync().ConfigureAwait(false); goto retry; } }