예제 #1
0
 /// <summary>
 /// Invokes the expressions when <see cref="ConditionResult"/> is <c>true</c>.
 /// </summary>
 /// <param name="expression">The delegate that is invoked when <see cref="ConditionResult"/> is <c>true</c>.</param>
 public void InvokeWhenTrue(Action <TTuple> expression)
 {
     if (ConditionResult)
     {
         ActionFactory.Invoke(expression, Tuple);
     }
 }
 private static bool TryExecuteActionCore <TTuple>(ActionFactory <TTuple> factory) where TTuple : Template
 {
     try
     {
         factory.ExecuteMethod();
         return(true);
     }
     catch (Exception)
     {
         return(false);
     }
 }
        /// <summary>
        /// Returns a value that indicates whether the specified <paramref name="method"/> can be invoked without an exception.
        /// </summary>
        /// <typeparam name="T1">The type of the first parameter of the method.</typeparam>
        /// <typeparam name="T2">The type of the second parameter of the method.</typeparam>
        /// <typeparam name="T3">The type of the third parameter of the method.</typeparam>
        /// <typeparam name="T4">The type of the fourth parameter of the method.</typeparam>
        /// <typeparam name="T5">The type of the fifth parameter of the method.</typeparam>
        /// <param name="method">The delegate to invoke.</param>
        /// <param name="arg1">The first parameter of the <paramref name="method"/>.</param>
        /// <param name="arg2">The second parameter of the <paramref name="method"/>.</param>
        /// <param name="arg3">The third parameter of the <paramref name="method"/>.</param>
        /// <param name="arg4">The fourth parameter of the <paramref name="method"/>.</param>
        /// <param name="arg5">The fifth parameter of the <paramref name="method"/>.</param>
        /// <returns><c>true</c> if the delegate <paramref name="method"/> was invoked without triggering an exception; otherwise <c>false</c>.</returns>
        public static bool TryExecuteAction <T1, T2, T3, T4, T5>(Action <T1, T2, T3, T4, T5> method, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
        {
            var factory = ActionFactory.Create(method, arg1, arg2, arg3, arg4, arg5);

            return(TryExecuteActionCore(factory));
        }
        /// <summary>
        /// Returns a value that indicates whether the specified <paramref name="method"/> can be invoked without an exception.
        /// </summary>
        /// <typeparam name="T1">The type of the first parameter of the method.</typeparam>
        /// <typeparam name="T2">The type of the second parameter of the method.</typeparam>
        /// <typeparam name="T3">The type of the third parameter of the method.</typeparam>
        /// <param name="method">The delegate to invoke.</param>
        /// <param name="arg1">The first parameter of the <paramref name="method"/>.</param>
        /// <param name="arg2">The second parameter of the <paramref name="method"/>.</param>
        /// <param name="arg3">The third parameter of the <paramref name="method"/>.</param>
        /// <returns><c>true</c> if the delegate <paramref name="method"/> was invoked without triggering an exception; otherwise <c>false</c>.</returns>
        public static bool TryExecuteAction <T1, T2, T3>(Action <T1, T2, T3> method, T1 arg1, T2 arg2, T3 arg3)
        {
            var factory = ActionFactory.Create(method, arg1, arg2, arg3);

            return(TryExecuteActionCore(factory));
        }
        /// <summary>
        /// Returns a value that indicates whether the specified <paramref name="method"/> can be invoked without an exception.
        /// </summary>
        /// <typeparam name="T">The type of the parameter of the method.</typeparam>
        /// <param name="method">The delegate to invoke.</param>
        /// <param name="arg">The first parameter of the <paramref name="method"/>.</param>
        /// <returns><c>true</c> if the delegate <paramref name="method"/> was invoked without triggering an exception; otherwise <c>false</c>.</returns>
        public static bool TryExecuteAction <T>(Action <T> method, T arg)
        {
            var factory = ActionFactory.Create(method, arg);

            return(TryExecuteActionCore(factory));
        }
        /// <summary>
        /// Returns a value that indicates whether the specified <paramref name="method"/> can be invoked without an exception.
        /// </summary>
        /// <param name="method">The delegate to invoke.</param>
        /// <returns><c>true</c> if the delegate <paramref name="method"/> was invoked without triggering an exception; otherwise <c>false</c>.</returns>
        public static bool TryExecuteAction(Action method)
        {
            var factory = ActionFactory.Create(method);

            return(TryExecuteActionCore(factory));
        }
        private static void WithActionCore <TTuple>(ActionFactory <TTuple> factory, Action <TransientOperationOptions> setup = null) where TTuple : Template
        {
            var options = setup.ConfigureOptions();

            if (!options.EnableRecovery)
            {
                factory.ExecuteMethod();
                return;
            }
            DateTime         timestamp        = DateTime.UtcNow;
            TimeSpan         latency          = TimeSpan.Zero;
            TimeSpan         totalWaitTime    = TimeSpan.Zero;
            TimeSpan         lastWaitTime     = TimeSpan.Zero;
            bool             isTransientFault = false;
            bool             throwExceptions;
            List <Exception> aggregatedExceptions = new List <Exception>();

            for (int attempts = 0; ;)
            {
                TimeSpan waitTime = options.RetryStrategy(attempts);
                try
                {
                    if (latency > options.MaximumAllowedLatency)
                    {
                        throw new LatencyException(string.Format(CultureInfo.InvariantCulture, "The latency of the operation exceeded the allowed maximum value of {0} seconds. Actual latency was: {1} seconds.", options.MaximumAllowedLatency.TotalSeconds, latency.TotalSeconds));
                    }
                    factory.ExecuteMethod();
                    return;
                }
                catch (Exception ex)
                {
                    try
                    {
                        lock (aggregatedExceptions) { aggregatedExceptions.Insert(0, ex); }
                        isTransientFault = options.DetectionStrategy(ex);
                        if (attempts >= options.RetryAttempts)
                        {
                            throw;
                        }
                        if (!isTransientFault)
                        {
                            throw;
                        }
                        lastWaitTime  = waitTime;
                        totalWaitTime = totalWaitTime.Add(waitTime);
                        attempts++;
                        Sleep(waitTime);
                        latency = DateTime.UtcNow.Subtract(timestamp).Subtract(totalWaitTime);
                    }
                    catch (Exception)
                    {
                        throwExceptions = true;
                        if (isTransientFault)
                        {
                            var evidence = new TransientFaultEvidence(attempts, lastWaitTime, totalWaitTime, latency, new MethodDescriptor(factory.DelegateInfo).ToString());
                            aggregatedExceptions.InsertTransientFaultException(evidence);
                            FaultCallback?.Invoke(evidence);
                        }
                        break;
                    }
                }
            }
            if (throwExceptions)
            {
                throw new AggregateException(aggregatedExceptions);
            }
        }
        /// <summary>
        /// Repetitively executes the specified <paramref name="faultSensitiveMethod"/> until the operation is successful, the amount of retry attempts has been reached, or a failed operation is not considered related to transient fault condition.
        /// </summary>
        /// <typeparam name="T1">The type of the first parameter of the delegate <paramref name="faultSensitiveMethod"/>.</typeparam>
        /// <typeparam name="T2">The type of the second parameter of the delegate <paramref name="faultSensitiveMethod"/>.</typeparam>
        /// <typeparam name="T3">The type of the third parameter of the delegate <paramref name="faultSensitiveMethod"/>.</typeparam>
        /// <typeparam name="T4">The type of the fourth parameter of the delegate <paramref name="faultSensitiveMethod"/>.</typeparam>
        /// <typeparam name="T5">The type of the fifth parameter of the delegate <paramref name="faultSensitiveMethod"/>.</typeparam>
        /// <param name="faultSensitiveMethod">The fault sensitive delegate that is invoked until an operation is successful, the amount of retry attempts has been reached, or a failed operation is not considered related to transient fault condition.</param>
        /// <param name="arg1">The first parameter of the delegate <paramref name="faultSensitiveMethod"/>.</param>
        /// <param name="arg2">The second parameter of the delegate <paramref name="faultSensitiveMethod"/>.</param>
        /// <param name="arg3">The third parameter of the delegate <paramref name="faultSensitiveMethod"/>.</param>
        /// <param name="arg4">The fourth parameter of the delegate <paramref name="faultSensitiveMethod"/>.</param>
        /// <param name="arg5">The fifth parameter of the delegate <paramref name="faultSensitiveMethod"/>.</param>
        /// <param name="setup">The <see cref="TransientOperationOptions"/> which need to be configured.</param>
        public static void WithAction <T1, T2, T3, T4, T5>(Action <T1, T2, T3, T4, T5> faultSensitiveMethod, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, Action <TransientOperationOptions> setup = null)
        {
            var factory = ActionFactory.Create(faultSensitiveMethod, arg1, arg2, arg3, arg4, arg5);

            WithActionCore(factory, setup);
        }
        /// <summary>
        /// Repetitively executes the specified <paramref name="faultSensitiveMethod"/> until the operation is successful, the amount of retry attempts has been reached, or a failed operation is not considered related to transient fault condition.
        /// </summary>
        /// <typeparam name="T1">The type of the first parameter of the delegate <paramref name="faultSensitiveMethod"/>.</typeparam>
        /// <typeparam name="T2">The type of the second parameter of the delegate <paramref name="faultSensitiveMethod"/>.</typeparam>
        /// <param name="faultSensitiveMethod">The fault sensitive delegate that is invoked until an operation is successful, the amount of retry attempts has been reached, or a failed operation is not considered related to transient fault condition.</param>
        /// <param name="arg1">The first parameter of the delegate <paramref name="faultSensitiveMethod"/>.</param>
        /// <param name="arg2">The second parameter of the delegate <paramref name="faultSensitiveMethod"/>.</param>
        /// <param name="setup">The <see cref="TransientOperationOptions"/> which need to be configured.</param>
        public static void WithAction <T1, T2>(Action <T1, T2> faultSensitiveMethod, T1 arg1, T2 arg2, Action <TransientOperationOptions> setup = null)
        {
            var factory = ActionFactory.Create(faultSensitiveMethod, arg1, arg2);

            WithActionCore(factory, setup);
        }
        /// <summary>
        /// Repetitively executes the specified <paramref name="faultSensitiveMethod"/> until the operation is successful, the amount of retry attempts has been reached, or a failed operation is not considered related to transient fault condition.
        /// </summary>
        /// <param name="faultSensitiveMethod">The fault sensitive delegate that is invoked until an operation is successful, the amount of retry attempts has been reached, or a failed operation is not considered related to transient fault condition.</param>
        /// <param name="setup">The <see cref="TransientOperationOptions"/> which need to be configured.</param>
        public static void WithAction(Action faultSensitiveMethod, Action <TransientOperationOptions> setup = null)
        {
            var factory = ActionFactory.Create(faultSensitiveMethod);

            WithActionCore(factory, setup);
        }
예제 #11
0
        /// <summary>
        /// Invokes the specified delegate <paramref name="method"/> with a n-<paramref name="tuple"/> argument.
        /// </summary>
        /// <typeparam name="TTuple">The type of the n-tuple representation of a <see cref="Template"/>.</typeparam>
        /// <param name="method">The delegate to invoke.</param>
        /// <param name="tuple">The n-tuple argument of <paramref name="method"/>.</param>
        public static void Invoke <TTuple>(Action <TTuple> method, TTuple tuple) where TTuple : Template
        {
            ActionFactory <TTuple> factory = new ActionFactory <TTuple>(method, tuple);

            factory.ExecuteMethod();
        }