예제 #1
0
        public virtual bool CanRetry(RetryContext context)
        {
            Exception ex = context.LastException;

            // N.B. the contract is defined to include the initial attempt in the count.
            return((ex == null || RetryForException(ex)) && (context.RetryCount < _maxAttempts));
        }
예제 #2
0
        /// <summary>
        /// Keep executing the callback until it eiether succeeds or the policy dictates that we stop,
        /// in which case the most recent exception thrown by the callback will be rethrown.
        /// </summary>
        /// <param name="callback">Callback interface for an operation that can be retried</param>
        /// <returns>Return value of the callback</returns>
        /// <typeparam name="T">Return type</typeparam>
        public T Execute <T>(Func <RetryContext, T> callback)
        {
            Exception    lastException = null;
            RetryContext context       = new RetryContext(_retryPolicy.MaxAttempts, _retryPolicy.BackOffPeriod);

            while (_retryPolicy.CanRetry(context) && !context.IsExhausted)
            {
                try
                {
                    lastException = null;
                    return(callback(context));
                }
                catch (Exception ex)
                {
                    lastException = ex;
                    _retryPolicy.RegisterThrowable(context, ex);

                    if (!_retryPolicy.CanRetry(context))
                    {
                        // Rethrow last exception
                        throw;
                    }
                }

                var onRetryHandler = OnRetry;
                if (onRetryHandler != null)
                {
                    onRetryHandler(context);
                }

                _retryPolicy.BackOff(context);
            }

            return(_retryPolicy.HandleRetryExhausted <T>(context));
        }
예제 #3
0
        /// <summary>
        /// Keep executing the callback until it eiether succeeds or the policy dictates that we stop,
        /// in which case the most recent exception thrown by the callback will be rethrown.
        /// </summary>
        /// <param name="callback">Callback interface for an operation that can be retried</param>
        /// <returns>Return value of the callback</returns>
        /// <typeparam name="T">Return type</typeparam>
        public async Task <T> ExecuteAsync <T>(Func <RetryContext, Task <T> > callback)
        {
            Exception    lastException = null;
            RetryContext context       = new RetryContext(_retryPolicy.MaxAttempts, _retryPolicy.BackOffPeriod);

            while (_retryPolicy.CanRetry(context) && !context.IsExhausted)
            {
                try
                {
                    lastException = null;
                    return(await callback(context).ConfigureAwait(false));
                }
                catch (Exception ex)
                {
                    lastException = ex;
                    _retryPolicy.RegisterThrowable(context, ex);

                    if (!_retryPolicy.CanRetry(context))
                    {
                        // Rethrow last exception
                        throw;
                    }
                }

                var onRetryHandler = OnRetry;
                if (onRetryHandler != null)
                {
                    onRetryHandler(context);
                }

                await _retryPolicy.BackOffAsync(context).ConfigureAwait(false);
            }

            return(_retryPolicy.HandleRetryExhausted <T>(context));
        }
예제 #4
0
 public virtual T HandleRetryExhausted <T>(RetryContext context)
 {
     throw new ExhaustedRetryException("Retry exhausted after last attempt with no recovery path.", context.LastException);
 }
예제 #5
0
 public virtual Task BackOffAsync(RetryContext context)
 {
     return(Task.Delay(BackOffPeriod));
 }
예제 #6
0
 public virtual void BackOff(RetryContext context)
 {
     Thread.Sleep(BackOffPeriod);
 }
예제 #7
0
 public virtual void RegisterThrowable(RetryContext context, Exception exception)
 {
     context.RegisterException(exception);
 }