Esempio n. 1
0
        public Task ExplicitTripWorks()
        {
            var resilientOperation = ResilientOperation
                                     .From(() =>
            {
                throw new InvalidOperationException();

#pragma warning disable CS0162 // Unreachable code detected
                return(Task.FromResult(42));

#pragma warning restore CS0162 // Unreachable code detected
            })
                                     .WhenExceptionIs <InvalidOperationException>(async(op, ex) =>
            {
                if (op.CurrentAttempt <= 3)
                {
                    await op.RetryAfterAsync(TimeSpan.FromMilliseconds(100));
                }
                else
                {
                    op.DefaultCircuitBreaker.Trip(ex, TimeSpan.FromDays(1));
                }
            })
                                     .GetOperation();

            return(Assert.ThrowsAsync <CircuitBrokenException>(async() => await resilientOperation(CancellationToken.None)));
        }
Esempio n. 2
0
        public Task CircuitBreaksAfterConsecutiveFailures()
        {
            var resilientOperation = ResilientOperation
                                     .From(() =>
            {
                throw new Exception();

#pragma warning disable CS0162 // Unreachable code detected
                return(Task.FromResult(42));

#pragma warning restore CS0162 // Unreachable code detected
            })
                                     .WithCircuitBreaker(
                operationKey: nameof(CircuitBreaksAfterConsecutiveFailures),
                onMissingFactory: () => new CircuitBreaker(new ConsecutiveFailureCircuitBreakerStrategy(3)))
                                     .WhenExceptionIs <Exception>(async(op, ex) =>
            {
                if (op.CurrentAttempt <= 3)
                {
                    await op.RetryAfterAsync(TimeSpan.FromMilliseconds(100));
                }
            })
                                     .GetOperation();

            return(Assert.ThrowsAsync <CircuitBrokenException>(async() => await resilientOperation(CancellationToken.None)));
        }
        public async Task TimeoutExceptionRetried()
        {
            var retryWasHit = false;

            var resilientOperation = ResilientOperation.From(async() =>
            {
                await Task.Delay(100);

                return(42);
            })
                                     .TimeoutAfter(TimeSpan.FromMilliseconds(20))
                                     .WhenExceptionIs <TimeoutException>((op, ex) =>
            {
                if (op.Total.AttemptsExhausted == 0)
                {
                    retryWasHit = true;

                    op.Retry();
                }

                return(Task.CompletedTask);
            })
                                     .GetOperation();

            await Assert.ThrowsAsync <TimeoutException>(() => resilientOperation(CancellationToken.None));

            Assert.True(retryWasHit);
        }
Esempio n. 4
0
        public async Task ResilientFunctionReturnsAfterRetries()
        {
            int failureCount = 0;

            var resilientOperation = ResilientOperation.From(() =>
            {
                // Fail 3 times before succeeding
                if (failureCount < 3)
                {
                    failureCount++;
                    throw new Exception();
                }

                return(42);
            })
                                     .WhenExceptionIs <Exception>(async(op, ex) =>
            {
                if (op.Total.AttemptsExhausted < 3)
                {
                    await op.WaitThenRetryAsync(TimeSpan.FromMilliseconds(100));
                }
            })
                                     .GetOperation();


            Assert.Equal(42, await resilientOperation(CancellationToken.None));
        }
Esempio n. 5
0
        public Task TimeoutExceptionIsThrown()
        {
            var resilientOperation = ResilientOperation.From(() => Task.Delay(100))
                                     .TimeoutAfter(TimeSpan.FromMilliseconds(20))
                                     .GetOperation();

            return(Assert.ThrowsAsync <TimeoutException>(() => resilientOperation(CancellationToken.None)));
        }
Esempio n. 6
0
        public async Task ExceptionHandlersIncrementBackoff()
        {
            var backoffStrategy = Backoff
                                  .LinearlyFrom(TimeSpan.FromMilliseconds(250));

            int failureCount = 0;

            var resilientOperation =
                ResilientOperation.From(() =>
            {
                // Fail 3 times before succeeding
                if (failureCount < 3)
                {
                    failureCount++;
                    throw new Exception();
                }

                if (failureCount < 4)
                {
                    failureCount++;
                    return(Task.FromResult(5));
                }

                return(Task.FromResult(42));
            })
                .WhenExceptionIs <Exception>(async(op, ex) =>
            {
                if (op.CurrentAttempt <= 3)
                {
                    await op.RetryAfterAsync(backoffStrategy.Next());
                }
            })
                .WhenResult(value => value != 42, async(op, value) =>
            {
                if (op.CurrentAttempt <= 4)
                {
                    await op.RetryAfterAsync(backoffStrategy.Next());
                }
            })
                .WhenResult(value => value == 42, (op, ex) =>
            {
                op.Return(0);

                return(Task.CompletedTask);
            })
                .GetOperation();

            Assert.Equal(0, await resilientOperation(CancellationToken.None));
            Assert.Equal(4, failureCount);
            Assert.Equal(TimeSpan.FromMilliseconds(250 * 5), backoffStrategy.Next());
        }
Esempio n. 7
0
        public Task ThrowsOnceRetryHandlersAreExhausted()
        {
            var resilientOperation = ResilientOperation.From(() =>
            {
                throw new Exception();

#pragma warning disable CS0162 // Unreachable code detected
                return(Task.FromResult(42));

#pragma warning restore CS0162 // Unreachable code detected
            })
                                     .WhenExceptionIs <Exception>(async(op, ex) =>
            {
                if (op.CurrentAttempt <= 3)
                {
                    await op.RetryAfterAsync(TimeSpan.FromMilliseconds(100));
                }
            })
                                     .GetOperation();

            return(Assert.ThrowsAsync <Exception>(async() => await resilientOperation(CancellationToken.None)));
        }