private static bool TryExecuteActionCore <TTuple>(ActionFactory <TTuple> factory) where TTuple : Template { try { factory.ExecuteMethod(); return(true); } catch (Exception) { return(false); } }
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> /// 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(); }