Ejemplo n.º 1
0
        internal static RetryException TestException(RetryOptions options, IRetryExceptionTester retryExceptionTester, IEnumerable <Type> exceptionWhiteList, IEnumerable <Type> exceptionBlackList, Exception exception, int currentAttempt, TimeSpan elapsed, List <Exception> exceptions)
        {
            exceptions.Add(exception);

            //simplified WithRetry class, added better async support, added wait interval to RetryOptions, added support for exception white lists and black lists
            var type = exception.GetType();

            if (exceptionWhiteList != null && !exceptionWhiteList.Contains(type))
            {
                return(new RetryNotAllowedException(RetryNotAllowedReason.WhiteList, "Exception does not qualify for retry. See inner exception for details.", exception)
                {
                    Attempts = currentAttempt,
                    Duration = elapsed,
                    Exceptions = exceptions
                });
            }

            if (exceptionBlackList != null && exceptionBlackList.Contains(type))
            {
                return(new RetryNotAllowedException(RetryNotAllowedReason.BlackList, "Exception does not qualify for retry. See inner exception for details.", exception)
                {
                    Attempts = currentAttempt,
                    Duration = elapsed,
                    Exceptions = exceptions
                });
            }

            if (retryExceptionTester != null && exception != null && !retryExceptionTester.CanRetry(exception))
            {
                return(new RetryNotAllowedException(RetryNotAllowedReason.RetryTester, "Exception does not qualify for retry. See inner exception for details.", exception)
                {
                    Attempts = currentAttempt,
                    Duration = elapsed,
                    Exceptions = exceptions
                });
            }

            if (currentAttempt >= options.MaxAttempts)
            {
                return(new ExceededMaxAttemptsException($"Exceeded maximum attempts: {options.MaxAttempts}. See Exceptions property for details.")
                {
                    Attempts = currentAttempt,
                    Duration = elapsed,
                    Exceptions = exceptions
                });
            }

            if (elapsed >= options.Timeout)
            {
                return(new ExceededMaxWaitTimeException($"Exceeded maximum wait time: {options.Timeout} seconds. See Exceptions property for details.")
                {
                    Attempts = currentAttempt,
                    Duration = elapsed,
                    Exceptions = exceptions
                });
            }

            return(null);
        }
Ejemplo n.º 2
0
        public static TInterface Create <TInterface, TImplementation>(RetryOptions options, IRetryExceptionTester retryExceptionTester = null, IEnumerable <Type> exceptionWhiteList = null, IEnumerable <Type> exceptionBlackList = null)
            where TInterface : class
            where TImplementation : class, new()
        {
            var instance = Activator.CreateInstance <TImplementation>() as TInterface;

            return(Create(instance, options, retryExceptionTester, exceptionWhiteList, exceptionBlackList));
        }
Ejemplo n.º 3
0
        public static TInterface Create <TInterface>(TInterface instance, RetryOptions options, IRetryExceptionTester retryExceptionTester = null, IEnumerable <Type> exceptionWhiteList = null, IEnumerable <Type> exceptionBlackList = null) where TInterface : class
        {
            var result = Create <TInterface, RetryProxy>();

            var proxy = (result as RetryProxy);

            proxy._instance             = instance ?? throw new ArgumentNullException(nameof(instance));
            proxy._options              = options ?? throw new ArgumentNullException(nameof(options));
            proxy._retryExceptionTester = retryExceptionTester;
            proxy._exceptionWhiteList   = exceptionWhiteList;
            proxy._exceptionBlackList   = exceptionBlackList;

            return(result);
        }
Ejemplo n.º 4
0
        public static void Invoke(RetryOptions options, Action action, IRetryExceptionTester retryExceptionTester = null, IEnumerable <Type> exceptionWhiteList = null, IEnumerable <Type> exceptionBlackList = null)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            List <Exception> exceptions = null;

            var       waitTime       = options.InitialInterval;
            var       currentAttempt = 1;
            Exception exception      = null;

            var stopwatch = new Stopwatch();

            stopwatch.Start();

            var complete = false;

            while (!complete)
            {
                try
                {
                    action();
                    complete = true;
                }
                catch (TargetInvocationException ex)
                {
                    exception = ex.InnerException;
                }
                catch (AggregateException ex)
                {
                    exception = ex.GetBaseException();
                }
                catch (Exception ex)
                {
                    exception = ex;
                }

                // test the exception for can retry, exceeded max retry, and timeout
                if (exception != null)
                {
                    if (exceptions == null)
                    {
                        exceptions = new List <Exception>();
                    }

                    var retryException = TestException(options, retryExceptionTester, exceptionWhiteList, exceptionBlackList, exception, currentAttempt++, stopwatch.Elapsed, exceptions);
                    if (retryException != null)
                    {
                        throw retryException;
                    }
                }

                //reset exception for next attempt
                exception = null;

                // wait a bit before trying again
                Thread.Sleep(waitTime);

                // ratcheting up - allows wait times up to ~10 seconds per try
                waitTime = TimeSpan.FromMilliseconds(waitTime.TotalMilliseconds <= 110 ? waitTime.TotalMilliseconds * 1.25 : waitTime.TotalMilliseconds);
            }
        }
Ejemplo n.º 5
0
        public static T Invoke <T>(RetryOptions options, Func <T> function, IRetryExceptionTester retryExceptionTester = null, IEnumerable <Type> exceptionWhiteList = null, IEnumerable <Type> exceptionBlackList = null)
        {
            if (function == null)
            {
                throw new ArgumentNullException(nameof(function));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            var isAwaitable = function.Method.ReturnType.GetMethod(nameof(Task.GetAwaiter)) != null;

            if (isAwaitable)
            {
                throw new NotSupportedException("Use InvokeAsync<T> instead.");
            }

            var result = default(T);

            List <Exception> exceptions = null;

            var       waitTime       = options.InitialInterval;
            var       currentAttempt = 1;
            Exception exception      = null;

            var stopwatch = new Stopwatch();

            stopwatch.Start();

            var complete = false;

            while (!complete)
            {
                try
                {
                    result   = function();
                    complete = true;
                }
                catch (TargetInvocationException ex)
                {
                    exception = ex.InnerException;
                }
                catch (AggregateException ex)
                {
                    exception = ex.GetBaseException();
                }
                catch (Exception ex)
                {
                    exception = ex;
                }

                // test the exception for can retry, exceeded max retry, and timeout
                if (exception != null)
                {
                    if (exceptions == null)
                    {
                        exceptions = new List <Exception>();
                    }

                    var retryException = TestException(options, retryExceptionTester, exceptionWhiteList, exceptionBlackList, exception, currentAttempt++, stopwatch.Elapsed, exceptions);
                    if (retryException != null)
                    {
                        throw retryException;
                    }
                }

                //reset exception for next attempt
                exception = null;

                // wait a bit before trying again
                Thread.Sleep(waitTime);

                // ratcheting up - allows wait times up to ~10 seconds per try
                waitTime = TimeSpan.FromMilliseconds(waitTime.TotalMilliseconds <= 110 ? waitTime.TotalMilliseconds * 1.25 : waitTime.TotalMilliseconds);
            }
            return(result);
        }