public class Retry
{
public static ILog _log = LogManager.GetLogger(MethodInfo.GetCurrentMethod().DeclaringType);
int _retryAttempts = 3;
int _retryWaitSeconds = 1;
public Retry() { }
public Retry(int retryAttempts, int retryWaitSeconds)
{
_retryAttempts = retryAttempts;
_retryWaitSeconds = retryWaitSeconds;
}
public void Execute(Action action)
{
int attempt = 0;
while (attempt++ < _retryAttempts)
{
try
{
if (_log.IsDebugEnabled)
{
_log.DebugFormat("Retry attempt {0}/{1}", attempt, _retryAttempts);
}
action();
return;
}
catch (Exception e)
{
if (attempt >= _retryAttempts)
{
_log.ErrorFormat("Retry failed with {0} attempts", _retryAttempts);
throw e;
}
int wait = _retryWaitSeconds * attempt;
_log.Warn(string.Format("Retry attempt {0}/{1} failed, waiting {2}s", attempt, _retryAttempts, wait), e);
Thread.Sleep(1000 * wait);
}
}
}
public TResult Execute<TResult>(Func<TResult> func)
{
int attempt = 0;
while (attempt++ < _retryAttempts)
{
try
{
if (_log.IsDebugEnabled)
{
_log.DebugFormat("Retry attempt {0}/{1}", attempt, _retryAttempts);
}
return func();
}
catch (Exception e)
{
if (attempt >= _retryAttempts)
{
_log.ErrorFormat("Retry failed with {0} attempts", _retryAttempts);
throw e;
}
int wait = _retryWaitSeconds * attempt;
_log.Warn(string.Format("Retry attempt {0}/{1} failed, waiting {2}s", attempt, _retryAttempts, wait), e);
Thread.Sleep(1000 * wait);
}
}
throw new Exception("Retry failed");
}
}
[TestFixture]
public class TestRetry
{
[Test]
public void Test()
{
new Retry(3, 1).Execute(SuccessAction);
try
{
new Retry(3, 1).Execute(FailureAction);
}catch(Exception ex)
{
Console.WriteLine("Failed");
}
Console.WriteLine(new Retry(3, 1).Execute(() => ComplexAction("1", "2")));
Console.WriteLine(new Retry(3, 1).Execute(() => ObjectAction("John")).ToString());
Func<Person> func = () =>
{
return new Person() { Name = "John" };
};
Console.WriteLine(new Retry(3, 1).Execute(func));
}
private void FailureAction()
{
Console.WriteLine("{0}: Failed", DateTime.Now);
throw new Exception("Failed Exception");
}
private void SuccessAction()
{
Console.WriteLine("{0}: OK", DateTime.Now);
}
private string ComplexAction(string a, string b)
{
return String.Format("{0} {1}", a, b);
}
private Person ObjectAction(string name)
{
return new Person() { Name = name };
}
}
class Person
{
public string Name { get; set; }
public override string ToString()
{
return "My name is : " + Name;
}
}
Comments
Post a Comment