예제 #1
0
        /// <summary>
        /// Builds a <see cref="FallbackPolicy"/> which provides a fallback value if the main execution fails.  Executes the main delegate, but if this throws a handled exception or raises a handled result, first calls <paramref name="onFallback"/> with details of the handled exception or result and the execution context; then calls <paramref name="fallbackAction"/> and returns its result.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="fallbackAction">The fallback action.</param>
        /// <param name="onFallback">The action to call before invoking the fallback delegate.</param>
        /// <exception cref="ArgumentNullException">fallbackAction</exception>
        /// <exception cref="ArgumentNullException">onFallback</exception>
        /// <returns>The policy instance.</returns>
        public static FallbackPolicy <TResult> Fallback <TResult>(this PolicyBuilder <TResult> policyBuilder, Func <DelegateResult <TResult>, Context, CancellationToken, TResult> fallbackAction, Action <DelegateResult <TResult>, Context> onFallback)
        {
            if (fallbackAction == null)
            {
                throw new ArgumentNullException(nameof(fallbackAction));
            }
            if (onFallback == null)
            {
                throw new ArgumentNullException(nameof(onFallback));
            }

            return(new FallbackPolicy <TResult>(
                       policyBuilder,
                       onFallback,
                       fallbackAction));
        }
예제 #2
0
        /// <summary>
        /// Builds a <see cref="FallbackPolicy"/> which provides a fallback action if the main execution fails.  Executes the main delegate, but if this throws a handled exception, first calls <paramref name="onFallback"/> with details of the handled exception and the execution context; then calls <paramref name="fallbackAction"/>.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="fallbackAction">The fallback action.</param>
        /// <param name="onFallback">The action to call before invoking the fallback delegate.</param>
        /// <exception cref="ArgumentNullException">fallbackAction</exception>
        /// <exception cref="ArgumentNullException">onFallback</exception>
        /// <returns>The policy instance.</returns>
        public static FallbackPolicy Fallback(this PolicyBuilder policyBuilder, Action <Exception, Context, CancellationToken> fallbackAction, Action <Exception, Context> onFallback)
        {
            if (fallbackAction == null)
            {
                throw new ArgumentNullException(nameof(fallbackAction));
            }
            if (onFallback == null)
            {
                throw new ArgumentNullException(nameof(onFallback));
            }

            return(new FallbackPolicy(
                       policyBuilder,
                       onFallback,
                       fallbackAction));
        }
예제 #3
0
        /// <summary>
        /// Builds a <see cref="Policy"/> that will retry indefinitely
        /// calling <paramref name="onRetry"/> on each retry with the raised exception.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentNullException">onRetry</exception>
        public static RetryPolicy RetryForever(this PolicyBuilder policyBuilder, Action <Exception> onRetry)
        {
            if (onRetry == null)
            {
                throw new ArgumentNullException("onRetry");
            }

            return(new RetryPolicy(
                       (action, context) => RetryEngine.Implementation(
                           action,
                           policyBuilder.ExceptionPredicates,
                           () => new RetryPolicyState(onRetry)
                           ),
                       policyBuilder.ExceptionPredicates
                       ));
        }
예제 #4
0
        /// <summary>
        /// Builds a <see cref="Policy"/> that will retry indefinitely
        /// calling <paramref name="onRetry"/> on each retry with the raised exception, retry count and context data.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentNullException">onRetry</exception>
        public static RetryPolicy RetryForever(this PolicyBuilder policyBuilder, Action <Exception, int, Context> onRetry)
        {
            if (onRetry == null)
            {
                throw new ArgumentNullException(nameof(onRetry));
            }

            return(new RetryPolicy((action, context, cancellationToken) => RetryEngine.Implementation(
                                       (ctx, ct) => { action(ctx, ct); return EmptyStruct.Instance; },
                                       context,
                                       cancellationToken,
                                       policyBuilder.ExceptionPredicates,
                                       PredicateHelper <EmptyStruct> .EmptyResultPredicates,
                                       () => new RetryStateRetryForeverWithCount <EmptyStruct>((outcome, i, ctx) => onRetry(outcome.Exception, i, ctx), context)
                                       ), policyBuilder.ExceptionPredicates));
        }
예제 #5
0
        /// <summary>
        /// Builds an <see cref="AsyncFallbackPolicy{TResult}"/> which provides a fallback value if the main execution fails.  Executes the main delegate asynchronously, but if this throws a handled exception or raises a handled result, first asynchronously calls <paramref name="onFallbackAsync"/> with details of the handled exception or result; then asynchronously calls <paramref name="fallbackAction"/> and returns its result.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="fallbackAction">The fallback delegate.</param>
        /// <param name="onFallbackAsync">The action to call asynchronously before invoking the fallback delegate.</param>
        /// <exception cref="System.ArgumentNullException">fallbackAction</exception>
        /// <exception cref="System.ArgumentNullException">onFallbackAsync</exception>
        /// <returns>The policy instance.</returns>
        public static AsyncFallbackPolicy <TResult> FallbackAsync <TResult>(this PolicyBuilder <TResult> policyBuilder, Func <CancellationToken, Task <TResult> > fallbackAction, Func <DelegateResult <TResult>, Task> onFallbackAsync)
        {
            if (fallbackAction == null)
            {
                throw new ArgumentNullException(nameof(fallbackAction));
            }
            if (onFallbackAsync == null)
            {
                throw new ArgumentNullException(nameof(onFallbackAsync));
            }

            return(policyBuilder.FallbackAsync(
                       (outcome, ctx, ct) => fallbackAction(ct),
                       (outcome, context) => onFallbackAsync(outcome)
                       ));
        }
예제 #6
0
        /// <summary>
        /// Builds a <see cref="Policy"/> that will wait and retry indefinitely until the action succeeds,
        /// calling <paramref name="onRetry"/> on each retry with the raised exception and execution context.
        ///     On each retry, the duration to wait is calculated by calling <paramref name="sleepDurationProvider" /> with
        ///     the current retry number (1 for first retry, 2 for second etc), previous execution and execution context.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="sleepDurationProvider">A function providing the duration to wait before retrying.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="ArgumentNullException">sleepDurationProvider</exception>
        /// <exception cref="ArgumentNullException">onRetry</exception>
        public static RetryPolicy WaitAndRetryForever(this PolicyBuilder policyBuilder, Func <int, Exception, Context, TimeSpan> sleepDurationProvider, Action <Exception, TimeSpan, Context> onRetry)
        {
            if (sleepDurationProvider == null)
            {
                throw new ArgumentNullException(nameof(sleepDurationProvider));
            }
            if (onRetry == null)
            {
                throw new ArgumentNullException(nameof(onRetry));
            }

            return(new RetryPolicy(
                       policyBuilder,
                       (outcome, timespan, _, ctx) => onRetry(outcome, timespan, ctx),
                       sleepDurationProvider: sleepDurationProvider));
        }
예제 #7
0
        /// <summary>
        /// Builds a <see cref="Policy"/> that will retry <paramref name="retryCount"/> times
        /// calling <paramref name="onRetry"/> on each retry with the raised exception, retry count and context data.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="retryCount">The retry count.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="ArgumentOutOfRangeException">retryCount;Value must be greater than or equal to zero.</exception>
        /// <exception cref="ArgumentNullException">onRetry</exception>
        public static RetryPolicy Retry(this PolicyBuilder policyBuilder, int retryCount, Action <Exception, int, Context> onRetry)
        {
            if (retryCount < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(retryCount), "Value must be greater than or equal to zero.");
            }
            if (onRetry == null)
            {
                throw new ArgumentNullException(nameof(onRetry));
            }

            return(new RetryPolicy(
                       policyBuilder,
                       (outcome, _, i, ctx) => onRetry(outcome, i, ctx),
                       retryCount));
        }
예제 #8
0
        /// <summary>
        /// Builds a <see cref="Policy{TResult}"/> that will retry <paramref name="retryCount"/> times
        /// calling <paramref name="onRetry"/> on each retry with the handled exception or result, retry count and context data.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="retryCount">The retry count.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="ArgumentOutOfRangeException">retryCount;Value must be greater than or equal to zero.</exception>
        /// <exception cref="ArgumentNullException">onRetry</exception>
        public static RetryPolicy <TResult> Retry <TResult>(this PolicyBuilder <TResult> policyBuilder, int retryCount, Action <DelegateResult <TResult>, int, Context> onRetry)
        {
            if (retryCount < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(retryCount), "Value must be greater than or equal to zero.");
            }
            if (onRetry == null)
            {
                throw new ArgumentNullException(nameof(onRetry));
            }

            return(new RetryPolicy <TResult>(
                       policyBuilder,
                       (outcome, timespan, i, ctx) => onRetry(outcome, i, ctx),
                       retryCount));
        }
예제 #9
0
        /// <summary>
        /// Builds a <see cref="Policy"/> that will wait and retry indefinitely until the action succeeds,
        /// calling <paramref name="onRetry"/> on each retry with the handled exception or result and retry count.
        ///     On each retry, the duration to wait is calculated by calling <paramref name="sleepDurationProvider" /> with
        ///     the current retry number (1 for first retry, 2 for second etc)
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="sleepDurationProvider">A function providing the duration to wait before retrying.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentNullException">sleepDurationProvider</exception>
        /// <exception cref="System.ArgumentNullException">onRetry</exception>
        public static RetryPolicy <TResult> WaitAndRetryForever <TResult>(this PolicyBuilder <TResult> policyBuilder, Func <int, TimeSpan> sleepDurationProvider, Action <DelegateResult <TResult>, int, TimeSpan> onRetry)
        {
            if (sleepDurationProvider == null)
            {
                throw new ArgumentNullException(nameof(sleepDurationProvider));
            }
            if (onRetry == null)
            {
                throw new ArgumentNullException(nameof(onRetry));
            }

            return(policyBuilder.WaitAndRetryForever(
                       (retryCount, outcome, context) => sleepDurationProvider(retryCount),
                       (outcome, i, timespan, context) => onRetry(outcome, i, timespan)
                       ));
        }
예제 #10
0
        /// <summary>
        /// Builds a <see cref="FallbackPolicy"/> which provides a fallback action if the main execution fails.  Executes the main delegate asynchronously, but if this throws a handled exception, first asynchronously calls <paramref name="onFallbackAsync"/> with details of the handled exception; then asynchronously calls <paramref name="fallbackAction"/>.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="fallbackAction">The fallback delegate.</param>
        /// <param name="onFallbackAsync">The action to call asynchronously before invoking the fallback delegate.</param>
        /// <exception cref="System.ArgumentNullException">fallbackAction</exception>
        /// <exception cref="System.ArgumentNullException">onFallbackAsync</exception>
        /// <returns>The policy instance.</returns>
        public static FallbackPolicy FallbackAsync(this PolicyBuilder policyBuilder, Func <CancellationToken, Task> fallbackAction, Func <Exception, Task> onFallbackAsync)
        {
            if (fallbackAction == null)
            {
                throw new ArgumentNullException(nameof(fallbackAction));
            }
            if (onFallbackAsync == null)
            {
                throw new ArgumentNullException(nameof(onFallbackAsync));
            }

            return(policyBuilder.FallbackAsync(
                       (outcome, ctx, ct) => fallbackAction(ct),
                       (outcome, context) => onFallbackAsync(outcome)
                       ));
        }
예제 #11
0
        /// <summary>
        /// Builds a <see cref="Policy{TResult}"/> that will wait and retry indefinitely until the action succeeds,
        /// calling <paramref name="onRetry"/> on each retry with the handled exception or result and execution context.
        ///     On each retry, the duration to wait is calculated by calling <paramref name="sleepDurationProvider" /> with
        ///     the current retry number (1 for first retry, 2 for second etc), previous execution result and execution context.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="sleepDurationProvider">A function providing the duration to wait before retrying.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="ArgumentNullException">sleepDurationProvider</exception>
        /// <exception cref="ArgumentNullException">onRetry</exception>
        public static RetryPolicy <TResult> WaitAndRetryForever <TResult>(this PolicyBuilder <TResult> policyBuilder, Func <int, DelegateResult <TResult>, Context, TimeSpan> sleepDurationProvider, Action <DelegateResult <TResult>, TimeSpan, Context> onRetry)
        {
            if (sleepDurationProvider == null)
            {
                throw new ArgumentNullException(nameof(sleepDurationProvider));
            }
            if (onRetry == null)
            {
                throw new ArgumentNullException(nameof(onRetry));
            }

            return(new RetryPolicy <TResult>(
                       policyBuilder,
                       (outcome, timespan, i, ctx) => onRetry(outcome, timespan, ctx),
                       sleepDurationProvider: sleepDurationProvider));
        }
예제 #12
0
        /// <summary>
        /// Builds a <see cref="Policy"/> that will wait and retry indefinitely until the action succeeds,
        /// calling <paramref name="onRetry"/> on each retry with the raised exception and retry count.
        ///     On each retry, the duration to wait is calculated by calling <paramref name="sleepDurationProvider" /> with
        ///     the current retry number (1 for first retry, 2 for second etc)
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="sleepDurationProvider">A function providing the duration to wait before retrying.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentNullException">sleepDurationProvider</exception>
        /// <exception cref="System.ArgumentNullException">onRetry</exception>
        public static RetryPolicy WaitAndRetryForever(this PolicyBuilder policyBuilder, Func <int, TimeSpan> sleepDurationProvider, Action <Exception, int, TimeSpan> onRetry)
        {
            if (sleepDurationProvider == null)
            {
                throw new ArgumentNullException(nameof(sleepDurationProvider));
            }
            if (onRetry == null)
            {
                throw new ArgumentNullException(nameof(onRetry));
            }

            return(policyBuilder.WaitAndRetryForever(
                       (retryCount, exception, context) => sleepDurationProvider(retryCount),
                       (exception, i, timespan, context) => onRetry(exception, i, timespan)
                       ));
        }
예제 #13
0
        /// <summary>
        /// Builds an <see cref="AsyncFallbackPolicy{TResult}"/> which provides a fallback value if the main execution fails.  Executes the main delegate asynchronously, but if this throws a handled exception or raises a handled result, first asynchronously calls <paramref name="onFallbackAsync"/> with details of the handled exception or result and the execution context; then asynchronously calls <paramref name="fallbackAction"/> and returns its result.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="fallbackAction">The fallback delegate.</param>
        /// <param name="onFallbackAsync">The action to call asynchronously before invoking the fallback delegate.</param>
        /// <exception cref="System.ArgumentNullException">fallbackAction</exception>
        /// <exception cref="System.ArgumentNullException">onFallbackAsync</exception>
        /// <returns>The policy instance.</returns>
        public static AsyncFallbackPolicy <TResult> FallbackAsync <TResult>(this PolicyBuilder <TResult> policyBuilder, Func <DelegateResult <TResult>, Context, CancellationToken, Task <TResult> > fallbackAction, Func <DelegateResult <TResult>, Context, Task> onFallbackAsync)
        {
            if (fallbackAction == null)
            {
                throw new ArgumentNullException(nameof(fallbackAction));
            }
            if (onFallbackAsync == null)
            {
                throw new ArgumentNullException(nameof(onFallbackAsync));
            }

            return(new AsyncFallbackPolicy <TResult>(
                       policyBuilder,
                       onFallbackAsync,
                       fallbackAction));
        }
예제 #14
0
        /// <summary>
        ///     Builds a <see cref="Policy" /> that will retry indefinitely
        ///     calling <paramref name="onRetry" /> on each retry with the raised exception.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentNullException">onRetry</exception>
        public static Policy RetryForeverAsync(this PolicyBuilder policyBuilder, Action <Exception> onRetry)
        {
            if (onRetry == null)
            {
                throw new ArgumentNullException("onRetry");
            }

            return(new Policy(
                       action => RetryPolicy.ImplementationAsync(
                           action,
                           policyBuilder.ExceptionPredicates,
                           () => new RetryPolicyState(onRetry)
                           ),
                       policyBuilder.ExceptionPredicates
                       ));
        }
예제 #15
0
        /// <summary>
        /// Builds a <see cref="Policy"/> that will retry indefinitely
        /// calling <paramref name="onRetry"/> on each retry with the raised exception.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentNullException">onRetry</exception>
        public static RetryPolicy RetryForever(this PolicyBuilder policyBuilder, Action <Exception> onRetry)
        {
            if (onRetry == null)
            {
                throw new ArgumentNullException("onRetry");
            }

            return(new RetryPolicy(
                       (action, context) => RetryEngine.Implementation(
                           () => { action(); return EmptyStruct.Instance; },
                           policyBuilder.ExceptionPredicates,
                           Enumerable.Empty <ResultPredicate <EmptyStruct> >(),
                           () => new RetryPolicyState <EmptyStruct>(outcome => onRetry(outcome.Exception))
                           ),
                       policyBuilder.ExceptionPredicates
                       ));
        }
예제 #16
0
        /// <summary>
        /// <para> Builds a <see cref="Policy" /> that will function like a Circuit Breaker.</para>
        /// <para>The circuit will break if, within any timeslice of duration <paramref name="samplingDuration"/>, the proportion of actions resulting in a handled exception exceeds <paramref name="failureThreshold"/>, provided also that the number of actions through the circuit in the timeslice is at least <paramref name="minimumThroughput" />. </para>
        /// <para>The circuit will stay broken for the <paramref name="durationOfBreak" />. Any attempt to execute this policy
        /// while the circuit is broken, will immediately throw a <see cref="BrokenCircuitException" /> containing the exception
        /// that broke the circuit.
        /// </para>
        /// <para>If the first action after the break duration period results in a handled exception, the circuit will break
        /// again for another <paramref name="durationOfBreak" />; if no exception is thrown, the circuit will reset.
        /// </para>
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="failureThreshold">The failure threshold at which the circuit will break (a number between 0 and 1; eg 0.5 represents breaking if 50% or more of actions result in a handled failure.</param>
        /// <param name="samplingDuration">The duration of the timeslice over which failure ratios are assessed.</param>
        /// <param name="minimumThroughput">The minimum throughput: this many actions or more must pass through the circuit in the timeslice, for statistics to be considered significant and the circuit-breaker to come into action.</param>
        /// <param name="durationOfBreak">The duration the circuit will stay open before resetting.</param>
        /// <param name="onBreak">The action to call when the circuit transitions to an <see cref="CircuitState.Open" /> state.</param>
        /// <param name="onReset">The action to call when the circuit resets to a <see cref="CircuitState.Closed" /> state.</param>
        /// <param name="onHalfOpen">The action to call when the circuit transitions to <see cref="CircuitState.HalfOpen" /> state, ready to try action executions again.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentOutOfRangeException">exceptionsAllowedBeforeBreaking;Value must be greater than zero.</exception>
        /// <exception cref="System.ArgumentNullException">
        /// onBreak
        /// or
        /// onReset
        /// or
        /// onHalfOpen
        /// </exception>
        /// <exception cref="ArgumentNullException">exceptionsAllowedBeforeBreaking;Value must be greater than zero.</exception>
        /// <exception cref="ArgumentNullException">onBreak</exception>
        /// <exception cref="ArgumentNullException">onReset</exception>
        /// <remarks>(see "Release It!" by Michael T. Nygard fi)</remarks>
        public static CircuitBreakerPolicy AdvancedCircuitBreaker(this PolicyBuilder policyBuilder, double failureThreshold, TimeSpan samplingDuration, int minimumThroughput, TimeSpan durationOfBreak, Action <Exception, TimeSpan, Context> onBreak, Action <Context> onReset, Action onHalfOpen)
        {
            var resolutionOfCircuit = TimeSpan.FromTicks(AdvancedCircuitController.ResolutionOfCircuitTimer);

            if (failureThreshold <= 0)
            {
                throw new ArgumentOutOfRangeException("failureThreshold", "Value must be greater than zero.");
            }
            if (failureThreshold > 1)
            {
                throw new ArgumentOutOfRangeException("failureThreshold", "Value must be less than or equal to one.");
            }
            if (samplingDuration < resolutionOfCircuit)
            {
                throw new ArgumentOutOfRangeException("samplingDuration", String.Format("Value must be equal to or greater than {0} milliseconds. This is the minimum resolution of the CircuitBreaker timer.", resolutionOfCircuit.TotalMilliseconds));
            }
            if (minimumThroughput <= 1)
            {
                throw new ArgumentOutOfRangeException("minimumThroughput", "Value must be greater than one.");
            }
            if (durationOfBreak < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException("durationOfBreak", "Value must be greater than zero.");
            }

            if (onBreak == null)
            {
                throw new ArgumentNullException("onBreak");
            }
            if (onReset == null)
            {
                throw new ArgumentNullException("onReset");
            }
            if (onHalfOpen == null)
            {
                throw new ArgumentNullException("onHalfOpen");
            }

            var breakerController = new AdvancedCircuitController(failureThreshold, samplingDuration, minimumThroughput, durationOfBreak, onBreak, onReset, onHalfOpen);

            return(new CircuitBreakerPolicy(
                       (action, context) => CircuitBreakerEngine.Implementation(action, context, policyBuilder.ExceptionPredicates, breakerController),
                       policyBuilder.ExceptionPredicates,
                       breakerController
                       ));
        }
예제 #17
0
        /// <summary>
        /// Builds a <see cref="Policy"/> that will wait and retry as many times as there are provided <paramref name="sleepDurations"/>
        /// calling <paramref name="onRetry"/> on each retry with the raised exception, current sleep duration, retry count and context data.
        /// On each retry, the duration to wait is the current <paramref name="sleepDurations"/> item.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="sleepDurations">The sleep durations to wait for on each retry.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentNullException">
        /// sleepDurations
        /// or
        /// onRetry
        /// </exception>
        public static RetryPolicy WaitAndRetry(this PolicyBuilder policyBuilder, IEnumerable <TimeSpan> sleepDurations, Action <Exception, TimeSpan, int, Context> onRetry)
        {
            if (sleepDurations == null)
            {
                throw new ArgumentNullException(nameof(sleepDurations));
            }
            if (onRetry == null)
            {
                throw new ArgumentNullException(nameof(onRetry));
            }

            return(new RetryPolicy(
                       policyBuilder,
                       onRetry,
                       sleepDurationsEnumerable: sleepDurations
                       ));
        }
        /// <summary>
        /// <para> Builds a <see cref="Policy"/> that will function like a Circuit Breaker.</para>
        /// <para>The circuit will break if <paramref name="handledEventsAllowedBeforeBreaking"/>
        /// exceptions or results that are handled by this policy are encountered consecutively. </para>
        /// <para>The circuit will stay broken for the <paramref name="durationOfBreak"/>. Any attempt to execute this policy
        /// while the circuit is broken, will immediately throw a <see cref="BrokenCircuitException"/> containing the exception or result
        /// that broke the circuit.
        /// </para>
        /// <para>If the first action after the break duration period results in a handled exception or result, the circuit will break
        /// again for another <paramref name="durationOfBreak"/>; if no exception or handled result is encountered, the circuit will reset.
        /// </para>
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="handledEventsAllowedBeforeBreaking">The number of exceptions or handled results that are allowed before opening the circuit.</param>
        /// <param name="durationOfBreak">The duration the circuit will stay open before resetting.</param>
        /// <param name="onBreak">The action to call when the circuit transitions to an <see cref="CircuitState.Open"/> state.</param>
        /// <param name="onReset">The action to call when the circuit resets to a <see cref="CircuitState.Closed"/> state.</param>
        /// <param name="onHalfOpen">The action to call when the circuit transitions to <see cref="CircuitState.HalfOpen"/> state, ready to try action executions again. </param>
        /// <returns>The policy instance.</returns>
        /// <remarks>(see "Release It!" by Michael T. Nygard fi)</remarks>
        /// <exception cref="System.ArgumentOutOfRangeException">handledEventsAllowedBeforeBreaking;Value must be greater than zero.</exception>
        /// <exception cref="ArgumentNullException">onBreak</exception>
        /// <exception cref="ArgumentNullException">onReset</exception>
        /// <exception cref="ArgumentNullException">onHalfOpen</exception>
        public static CircuitBreakerPolicy <TResult> CircuitBreakerAsync <TResult>(this PolicyBuilder <TResult> policyBuilder, int handledEventsAllowedBeforeBreaking, TimeSpan durationOfBreak, Action <DelegateResult <TResult>, TimeSpan, Context> onBreak, Action <Context> onReset, Action onHalfOpen)
        {
            if (handledEventsAllowedBeforeBreaking <= 0)
            {
                throw new ArgumentOutOfRangeException("handledEventsAllowedBeforeBreaking", "Value must be greater than zero.");
            }
            if (durationOfBreak < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException("durationOfBreak", "Value must be greater than zero.");
            }

            if (onBreak == null)
            {
                throw new ArgumentNullException("onBreak");
            }
            if (onReset == null)
            {
                throw new ArgumentNullException("onReset");
            }
            if (onHalfOpen == null)
            {
                throw new ArgumentNullException("onHalfOpen");
            }

            var breakerController = new ConsecutiveCountCircuitController <TResult>(
                handledEventsAllowedBeforeBreaking,
                durationOfBreak,
                onBreak,
                onReset,
                onHalfOpen);

            return(new CircuitBreakerPolicy <TResult>(
                       (action, context, cancellationToken, continueOnCapturedContext) =>
                       CircuitBreakerEngine.ImplementationAsync(
                           action,
                           context,
                           policyBuilder.ExceptionPredicates,
                           policyBuilder.ResultPredicates,
                           breakerController,
                           cancellationToken,
                           continueOnCapturedContext),
                       policyBuilder.ExceptionPredicates,
                       policyBuilder.ResultPredicates,
                       breakerController
                       ));
        }
예제 #19
0
        /// <summary>
        /// Builds a <see cref="Policy"/> that will retry <paramref name="retryCount"/> times
        /// calling <paramref name="onRetry"/> on each retry with the raised exception and retry count.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="retryCount">The retry count.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentOutOfRangeException">retryCount;Value must be greater than zero.</exception>
        /// <exception cref="System.ArgumentNullException">onRetry</exception>
        public static Policy Retry(this PolicyBuilder policyBuilder, int retryCount, Action <Exception, int> onRetry)
        {
            if (retryCount <= 0)
            {
                throw new ArgumentOutOfRangeException("retryCount", "Value must be greater than zero.");
            }
            if (onRetry == null)
            {
                throw new ArgumentNullException("onRetry");
            }

            return(new Policy(
                       action => RetryPolicy.Implementation(
                           action,
                           policyBuilder.ExceptionPredicates,
                           () => new RetryPolicyStateWithCount(retryCount, onRetry))));
        }
예제 #20
0
        /// <summary>
        ///     Builds a <see cref="Policy" /> that will retry indefinitely
        ///     calling <paramref name="onRetry" /> on each retry with the raised exception.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentNullException">onRetry</exception>
        public static RetryPolicy RetryForeverAsync(this PolicyBuilder policyBuilder, Action <Exception> onRetry)
        {
            if (onRetry == null)
            {
                throw new ArgumentNullException("onRetry");
            }

            return(new RetryPolicy(
                       (action, context, cancellationToken, continueOnCapturedContext) => RetryEngine.ImplementationAsync(
                           action,
                           cancellationToken,
                           policyBuilder.ExceptionPredicates,
                           () => new RetryPolicyState(onRetry),
                           continueOnCapturedContext),
                       policyBuilder.ExceptionPredicates
                       ));
        }
예제 #21
0
        /// <summary>
        /// Builds a <see cref="Policy"/> that will wait and retry as many times as there are provided <paramref name="sleepDurations"/>
        /// calling <paramref name="onRetry"/> on each retry with the raised exception, current sleep duration and
        /// execution context.
        /// On each retry, the duration to wait is the current <paramref name="sleepDurations"/> item.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="sleepDurations">The sleep durations to wait for on each retry.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentNullException">
        /// sleepDurations
        /// or
        /// onRetry
        /// </exception>
        public static ContextualPolicy WaitAndRetry(this PolicyBuilder policyBuilder, IEnumerable <TimeSpan> sleepDurations, Action <Exception, TimeSpan, Context> onRetry)
        {
            if (sleepDurations == null)
            {
                throw new ArgumentNullException("sleepDurations");
            }
            if (onRetry == null)
            {
                throw new ArgumentNullException("onRetry");
            }

            return(new ContextualPolicy((action, context) => RetryPolicy.Implementation(
                                            action,
                                            policyBuilder.ExceptionPredicates,
                                            () => new RetryPolicyStateWithSleep(sleepDurations, onRetry, context)
                                            )));
        }
예제 #22
0
        /// <summary>
        /// Builds a <see cref="Policy"/> that will retry <paramref name="retryCount"/> times
        /// calling <paramref name="onRetry"/> on each retry with the raised exception, retry count and context data.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="retryCount">The retry count.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentOutOfRangeException">retryCount;Value must be greater than or equal to zero.</exception>
        /// <exception cref="System.ArgumentNullException">onRetry</exception>
        public static RetryPolicy Retry(this PolicyBuilder policyBuilder, int retryCount, Action <Exception, int, Context> onRetry)
        {
            if (retryCount < 0)
            {
                throw new ArgumentOutOfRangeException("retryCount", "Value must be greater than or equal to zero.");
            }
            if (onRetry == null)
            {
                throw new ArgumentNullException("onRetry");
            }

            return(new RetryPolicy((action, context) => RetryEngine.Implementation(
                                       action,
                                       policyBuilder.ExceptionPredicates,
                                       () => new RetryPolicyStateWithCount(retryCount, onRetry, context)
                                       ), policyBuilder.ExceptionPredicates));
        }
예제 #23
0
        /// <summary>
        /// Builds a <see cref="Policy"/> that will retry indefinitely
        /// calling <paramref name="onRetry"/> on each retry with the handled exception or result and context data.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentNullException">onRetry</exception>
        public static RetryPolicy <TResult> RetryForever <TResult>(this PolicyBuilder <TResult> policyBuilder, Action <DelegateResult <TResult>, Context> onRetry)
        {
            if (onRetry == null)
            {
                throw new ArgumentNullException("onRetry");
            }

            return(new RetryPolicy <TResult>(
                       (action, context) => RetryEngine.Implementation(
                           action,
                           policyBuilder.ExceptionPredicates,
                           policyBuilder.ResultPredicates,
                           () => new RetryPolicyState <TResult>(onRetry, context)
                           ),
                       policyBuilder.ExceptionPredicates,
                       policyBuilder.ResultPredicates));
        }
예제 #24
0
        /// <summary>
        /// Builds a <see cref="Policy"/> that will wait and retry indefinitely
        /// calling <paramref name="onRetry"/> on each retry with the raised exception and
        /// execution context.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="sleepDurationProvider"></param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentNullException">sleepDurationProvider</exception>
        /// <exception cref="System.ArgumentNullException">onRetry</exception>
        public static RetryPolicy WaitAndRetryForever(this PolicyBuilder policyBuilder, Func <int, TimeSpan> sleepDurationProvider, Action <Exception, TimeSpan, Context> onRetry)
        {
            if (sleepDurationProvider == null)
            {
                throw new ArgumentNullException("sleepDurationProvider");
            }
            if (onRetry == null)
            {
                throw new ArgumentNullException("onRetry");
            }

            return(new RetryPolicy((action, context) => RetryEngine.Implementation(
                                       action,
                                       policyBuilder.ExceptionPredicates,
                                       () => new RetryPolicyStateWithSleepDurationProvider(sleepDurationProvider, onRetry, context)
                                       ), policyBuilder.ExceptionPredicates));
        }
예제 #25
0
        /// <summary>
        /// Builds a <see cref="Policy{TResult}"/> that will wait and retry as many times as there are provided <paramref name="sleepDurations"/>
        /// calling <paramref name="onRetry"/> on each retry with the handled exception or result, current sleep duration, retry count and context data.
        /// On each retry, the duration to wait is the current <paramref name="sleepDurations"/> item.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="sleepDurations">The sleep durations to wait for on each retry.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentNullException">
        /// sleepDurations
        /// or
        /// onRetry
        /// </exception>
        public static RetryPolicy <TResult> WaitAndRetry <TResult>(this PolicyBuilder <TResult> policyBuilder, IEnumerable <TimeSpan> sleepDurations, Action <DelegateResult <TResult>, TimeSpan, int, Context> onRetry)
        {
            if (sleepDurations == null)
            {
                throw new ArgumentNullException(nameof(sleepDurations));
            }
            if (onRetry == null)
            {
                throw new ArgumentNullException(nameof(onRetry));
            }

            return(new RetryPolicy <TResult>(
                       policyBuilder,
                       onRetry,
                       sleepDurationsEnumerable: sleepDurations
                       ));
        }
예제 #26
0
        /// <summary>
        /// Builds a <see cref="Policy"/> that will retry indefinitely
        /// calling <paramref name="onRetry"/> on each retry with the raised exception and context data.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentNullException">onRetry</exception>
        public static RetryPolicy RetryForeverAsync(this PolicyBuilder policyBuilder, Action <Exception, Context> onRetry)
        {
            if (onRetry == null)
            {
                throw new ArgumentNullException("onRetry");
            }

            return(new RetryPolicy((action, context, cancellationToken, continueOnCapturedContext) => RetryEngine.ImplementationAsync(
                                       action,
                                       cancellationToken,
                                       policyBuilder.ExceptionPredicates,
#pragma warning disable 1998
                                       () => new RetryPolicyState(async(e, c) => onRetry(e, c), context),
#pragma warning restore 1998
                                       continueOnCapturedContext
                                       ), policyBuilder.ExceptionPredicates));
        }
예제 #27
0
        /// <summary>
        /// <para> Builds a <see cref="Policy"/> that will function like a Circuit Breaker.</para>
        /// <para>The circuit will break if <paramref name="exceptionsAllowedBeforeBreaking"/>
        /// exceptions that are handled by this policy are raised consecutively. </para>
        /// <para>The circuit will stay broken for the <paramref name="durationOfBreak"/>. Any attempt to execute this policy
        /// while the circuit is broken, will immediately throw a <see cref="BrokenCircuitException"/> containing the exception
        /// that broke the circuit.
        /// </para>
        /// <para>If the first action after the break duration period results in a handled exception, the circuit will break
        /// again for another <paramref name="durationOfBreak"/>; if no exception is thrown, the circuit will reset.
        /// </para>
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="exceptionsAllowedBeforeBreaking">The number of exceptions that are allowed before opening the circuit.</param>
        /// <param name="durationOfBreak">The duration the circuit will stay open before resetting.</param>
        /// <param name="onBreak">The action to call when the circuit transitions to an <see cref="CircuitState.Open"/> state.</param>
        /// <param name="onReset">The action to call when the circuit resets to a <see cref="CircuitState.Closed"/> state.</param>
        /// <param name="onHalfOpen">The action to call when the circuit transitions to <see cref="CircuitState.HalfOpen"/> state, ready to try action executions again. </param>
        /// <returns>The policy instance.</returns>
        /// <remarks>(see "Release It!" by Michael T. Nygard fi)</remarks>
        /// <exception cref="System.ArgumentOutOfRangeException">exceptionsAllowedBeforeBreaking;Value must be greater than zero.</exception>
        /// <exception cref="ArgumentNullException">onBreak</exception>
        /// <exception cref="ArgumentNullException">onReset</exception>
        /// <exception cref="ArgumentNullException">onHalfOpen</exception>
        public static CircuitBreakerPolicy CircuitBreakerAsync(this PolicyBuilder policyBuilder, int exceptionsAllowedBeforeBreaking, TimeSpan durationOfBreak, Action <Exception, TimeSpan, Context> onBreak, Action <Context> onReset, Action onHalfOpen)
        {
            if (exceptionsAllowedBeforeBreaking <= 0)
            {
                throw new ArgumentOutOfRangeException("exceptionsAllowedBeforeBreaking", "Value must be greater than zero.");
            }
            if (durationOfBreak < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException("durationOfBreak", "Value must be greater than zero.");
            }

            if (onBreak == null)
            {
                throw new ArgumentNullException("onBreak");
            }
            if (onReset == null)
            {
                throw new ArgumentNullException("onReset");
            }
            if (onHalfOpen == null)
            {
                throw new ArgumentNullException("onHalfOpen");
            }

            var breakerController = new ConsecutiveCountCircuitController <EmptyStruct>(
                exceptionsAllowedBeforeBreaking,
                durationOfBreak,
                (outcome, timespan, context) => onBreak(outcome.Exception, timespan, context),
                onReset,
                onHalfOpen);

            return(new CircuitBreakerPolicy(
                       (action, context, cancellationToken, continueOnCapturedContext) =>
                       CircuitBreakerEngine.ImplementationAsync(
                           async ct => { await action(ct).ConfigureAwait(continueOnCapturedContext); return EmptyStruct.Instance; },
                           context,
                           policyBuilder.ExceptionPredicates,
                           PredicateHelper <EmptyStruct> .EmptyResultPredicates,
                           breakerController,
                           cancellationToken,
                           continueOnCapturedContext),
                       policyBuilder.ExceptionPredicates,
                       breakerController
                       ));
        }
예제 #28
0
        /// <summary>
        /// Builds a <see cref="Policy"/> that will retry <paramref name="retryCount"/> times
        /// calling <paramref name="onRetry"/> on each retry with the raised exception, retry count and context data.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="retryCount">The retry count.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentOutOfRangeException">retryCount;Value must be greater than or equal to zero.</exception>
        /// <exception cref="System.ArgumentNullException">onRetry</exception>
        public static RetryPolicy Retry(this PolicyBuilder policyBuilder, int retryCount, Action <Exception, int, Context> onRetry)
        {
            if (retryCount < 0)
            {
                throw new ArgumentOutOfRangeException("retryCount", "Value must be greater than or equal to zero.");
            }
            if (onRetry == null)
            {
                throw new ArgumentNullException("onRetry");
            }

            return(new RetryPolicy((action, context) => RetryEngine.Implementation(
                                       () => { action(); return EmptyStruct.Instance; },
                                       policyBuilder.ExceptionPredicates,
                                       Enumerable.Empty <ResultPredicate <EmptyStruct> >(),
                                       () => new RetryPolicyStateWithCount <EmptyStruct>(retryCount, (outcome, i, ctx) => onRetry(outcome.Exception, i, ctx), context)
                                       ), policyBuilder.ExceptionPredicates));
        }
예제 #29
0
        /// <summary>
        /// Builds a <see cref="Policy"/> that will wait and retry indefinitely
        /// calling <paramref name="onRetry"/> on each retry with the raised exception and
        /// execution context.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="sleepDurationProvider"></param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentNullException">sleepDurationProvider</exception>
        /// <exception cref="System.ArgumentNullException">onRetry</exception>
        public static RetryPolicy WaitAndRetryForever(this PolicyBuilder policyBuilder, Func <int, TimeSpan> sleepDurationProvider, Action <Exception, TimeSpan, Context> onRetry)
        {
            if (sleepDurationProvider == null)
            {
                throw new ArgumentNullException("sleepDurationProvider");
            }
            if (onRetry == null)
            {
                throw new ArgumentNullException("onRetry");
            }

            return(new RetryPolicy((action, context) => RetryEngine.Implementation(
                                       () => { action(); return EmptyStruct.Instance; },
                                       policyBuilder.ExceptionPredicates,
                                       Enumerable.Empty <ResultPredicate <EmptyStruct> >(),
                                       () => new RetryPolicyStateWithSleepDurationProvider <EmptyStruct>(sleepDurationProvider, (outcome, timespan, ctx) => onRetry(outcome.Exception, timespan, ctx), context)
                                       ), policyBuilder.ExceptionPredicates));
        }
예제 #30
0
        /// <summary>
        /// Builds a <see cref="Policy"/> that will retry indefinitely
        /// calling <paramref name="onRetry"/> on each retry with the handled exception or result.
        /// </summary>
        /// <param name="policyBuilder">The policy builder.</param>
        /// <param name="onRetry">The action to call on each retry.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentNullException">onRetry</exception>
        public static RetryPolicy <TResult> RetryForever <TResult>(this PolicyBuilder <TResult> policyBuilder, Action <Exception> onRetry)
        {
            if (onRetry == null)
            {
                throw new ArgumentNullException("onRetry");
            }

            return(new RetryPolicy <TResult>(
                       (action, context, cancellationToken) => RetryEngine.Implementation(
                           action,
                           cancellationToken,
                           policyBuilder.ExceptionPredicates,
                           policyBuilder.ResultPredicates,
                           () => new RetryPolicyState <TResult>((outcome, ctx) => onRetry(outcome.Exception), context)
                           ),
                       policyBuilder.ExceptionPredicates,
                       policyBuilder.ResultPredicates
                       ));
        }