2
using System.Collections.Generic;
5
using System.Threading;
6
using ServiceStack.Logging;
8
namespace ServiceStack.Common
10
public static class ExecExtensions
12
public static void LogError(Type declaringType, string clientMethodName, Exception ex)
14
var log = LogManager.GetLogger(declaringType);
15
log.Error(string.Format("'{0}' threw an error on {1}: {2}", declaringType.FullName, clientMethodName, ex.Message), ex);
18
public static void ExecAll<T>(this IEnumerable<T> instances, Action<T> action)
20
foreach (var instance in instances)
28
LogError(instance.GetType(), action.GetType().Name, ex);
33
public static void ExecAllWithFirstOut<T, TReturn>(this IEnumerable<T> instances, Func<T, TReturn> action, ref TReturn firstResult)
35
foreach (var instance in instances)
39
var result = action(instance);
40
if (!Equals(firstResult, default(TReturn)))
47
LogError(instance.GetType(), action.GetType().Name, ex);
52
public static TReturn ExecReturnFirstWithResult<T, TReturn>(this IEnumerable<T> instances, Func<T, TReturn> action)
54
foreach (var instance in instances)
58
var result = action(instance);
59
if (!Equals(result, default(TReturn)))
66
LogError(instance.GetType(), action.GetType().Name, ex);
70
return default(TReturn);
73
public static void RetryUntilTrue(Func<bool> action, TimeSpan? timeOut)
76
var firstAttempt = DateTime.Now;
78
while (timeOut == null || DateTime.Now - firstAttempt < timeOut.Value)
85
SleepBackOffMultiplier(i);
88
throw new TimeoutException(string.Format("Exceeded timeout of {0}", timeOut.Value));
91
public static void RetryOnException(Action action, TimeSpan? timeOut)
94
Exception lastEx = null;
95
var firstAttempt = DateTime.Now;
97
while (timeOut == null || DateTime.Now - firstAttempt < timeOut.Value)
109
SleepBackOffMultiplier(i);
113
throw new TimeoutException(string.Format("Exceeded timeout of {0}", timeOut.Value), lastEx);
116
public static void RetryOnException(Action action, int maxRetries)
118
for (var i = 0; i < maxRetries; i++)
127
if (i == maxRetries - 1) throw;
129
SleepBackOffMultiplier(i);
134
private static void SleepBackOffMultiplier(int i)
136
//exponential/random retry back-off.
137
var rand = new Random(Guid.NewGuid().GetHashCode());
138
var nextTry = rand.Next(
139
(int)Math.Pow(i, 2), (int)Math.Pow(i + 1, 2) + 1);
141
Thread.Sleep(nextTry);