wabbajack/Wabbajack.Common/CircuitBreaker.cs

144 lines
4.4 KiB
C#
Raw Permalink Normal View History

2021-09-27 12:42:46 +00:00
using System;
2020-06-01 20:26:03 +00:00
using System.Threading;
using System.Threading.Tasks;
2021-09-27 12:42:46 +00:00
using Microsoft.Extensions.Logging;
2021-10-23 16:51:17 +00:00
namespace Wabbajack.Common;
public static class CircuitBreaker
{
2021-10-23 16:51:17 +00:00
public static TimeSpan DEFAULT_DELAY = TimeSpan.FromMilliseconds(100);
public static int DEFAULT_DELAY_MULTIPLIER = 2;
public static int DEFAULT_RETRIES = 5;
public static async ValueTask<TR> WithAutoRetryAsync<TR, TE>(ILogger logger, Func<Task<TR>> f,
2021-10-23 16:51:17 +00:00
TimeSpan? delay = null, int? multipler = null, int? maxRetries = null) where TE : Exception
{
2021-10-23 16:51:17 +00:00
var retries = 0;
delay ??= DEFAULT_DELAY;
multipler ??= DEFAULT_DELAY_MULTIPLIER;
maxRetries ??= DEFAULT_RETRIES;
2021-10-23 16:51:17 +00:00
TOP:
try
{
2021-10-23 16:51:17 +00:00
return await f();
}
2021-10-23 16:51:17 +00:00
catch (TE ex)
2020-05-26 11:31:11 +00:00
{
2021-10-23 16:51:17 +00:00
retries += 1;
if (retries > maxRetries)
throw;
logger.LogWarning("(Retry {retries} of {maxRetries}), got exception {message}, waiting {wait}ms",
retries, maxRetries, ex.Message, delay!.Value.TotalMilliseconds);
await Task.Delay(delay.Value);
delay = delay * multipler;
goto TOP;
}
}
public static async ValueTask WithAutoRetryAsync<TE>(ILogger logger, Func<Task> f, TimeSpan? delay = null,
2021-10-23 16:51:17 +00:00
int? multipler = null, int? maxRetries = null) where TE : Exception
{
var retries = 0;
delay ??= DEFAULT_DELAY;
multipler ??= DEFAULT_DELAY_MULTIPLIER;
maxRetries ??= DEFAULT_RETRIES;
2020-05-26 11:31:11 +00:00
2021-10-23 16:51:17 +00:00
TOP:
try
{
await f();
}
2021-10-23 16:51:17 +00:00
catch (TE ex)
{
2021-10-23 16:51:17 +00:00
retries += 1;
if (retries > maxRetries)
throw;
logger.LogWarning("(Retry {retries} of {maxRetries}), got exception {message}, waiting {wait}ms",
retries, maxRetries, ex.Message, delay!.Value.TotalMilliseconds);
await Task.Delay(delay.Value);
delay = delay * multipler;
goto TOP;
}
}
2021-10-23 16:51:17 +00:00
public static async ValueTask WithAutoRetryAllAsync(ILogger logger, Func<ValueTask> f, TimeSpan? delay = null,
int? multipler = null, int? maxRetries = null)
{
var retries = 0;
delay ??= DEFAULT_DELAY;
multipler ??= DEFAULT_DELAY_MULTIPLIER;
maxRetries ??= DEFAULT_RETRIES;
TOP:
try
{
await f();
}
2021-10-23 16:51:17 +00:00
catch (Exception ex)
{
2021-10-23 16:51:17 +00:00
retries += 1;
if (retries > maxRetries)
throw;
logger.LogWarning("(Retry {retries} of {maxRetries}), got exception {message}, waiting {wait}ms",
retries, maxRetries, ex.Message, delay!.Value.TotalMilliseconds);
await Task.Delay(delay.Value);
delay = delay * multipler;
goto TOP;
}
}
public static async ValueTask<T> WithAutoRetryAllAsync<T>(ILogger logger, Func<ValueTask<T>> f,
TimeSpan? delay = null, int? multipler = null, int? maxRetries = null)
{
var retries = 0;
delay ??= DEFAULT_DELAY;
multipler ??= DEFAULT_DELAY_MULTIPLIER;
maxRetries ??= DEFAULT_RETRIES;
2021-10-23 16:51:17 +00:00
TOP:
try
{
return await f();
2020-05-26 11:31:11 +00:00
}
2021-10-23 16:51:17 +00:00
catch (Exception ex)
2020-06-01 20:26:03 +00:00
{
2021-10-23 16:51:17 +00:00
retries += 1;
if (retries > maxRetries)
throw;
await Task.Delay(delay.Value);
logger.LogWarning("(Retry {retries} of {maxRetries}), got exception {message}, waiting {wait}ms",
retries, maxRetries, ex.Message, delay!.Value.TotalMilliseconds);
delay = delay * multipler;
goto TOP;
2020-06-01 20:26:03 +00:00
}
2021-10-23 16:51:17 +00:00
}
2021-10-23 16:51:17 +00:00
public static void WithAutoRetry<TE>(ILogger logger, Action f, TimeSpan? delay = null, int? multipler = null,
int? maxRetries = null) where TE : Exception
{
var retries = 0;
delay ??= DEFAULT_DELAY;
multipler ??= DEFAULT_DELAY_MULTIPLIER;
maxRetries ??= DEFAULT_RETRIES;
TOP:
try
{
f();
}
catch (TE ex)
{
retries += 1;
if (retries > maxRetries)
throw;
logger.LogWarning("(Retry {retries} of {maxRetries}), got exception {message}, waiting {wait}ms",
retries, maxRetries, ex.Message, delay!.Value.TotalMilliseconds);
Thread.Sleep(delay.Value);
delay = delay * multipler;
goto TOP;
}
}
2021-09-27 12:42:46 +00:00
}