2023-04-12 11:53:55 +00:00
|
|
|
|
namespace Utils
|
|
|
|
|
{
|
|
|
|
|
public static class Time
|
|
|
|
|
{
|
|
|
|
|
public static void Sleep(TimeSpan span)
|
|
|
|
|
{
|
|
|
|
|
Thread.Sleep(span);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static T Wait<T>(Task<T> task)
|
|
|
|
|
{
|
|
|
|
|
task.Wait();
|
|
|
|
|
return task.Result;
|
|
|
|
|
}
|
2023-04-14 12:53:39 +00:00
|
|
|
|
|
|
|
|
|
public static string FormatDuration(TimeSpan d)
|
|
|
|
|
{
|
|
|
|
|
var result = "";
|
|
|
|
|
if (d.Days > 0) result += $"{d.Days} days, ";
|
|
|
|
|
if (d.Hours > 0) result += $"{d.Hours} hours, ";
|
|
|
|
|
if (d.Minutes > 0) result += $"{d.Minutes} mins, ";
|
|
|
|
|
result += $"{d.Seconds} secs";
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2023-04-17 14:28:07 +00:00
|
|
|
|
|
|
|
|
|
public static void WaitUntil(Func<bool> predicate, TimeSpan timeout, TimeSpan retryTime)
|
|
|
|
|
{
|
|
|
|
|
var start = DateTime.UtcNow;
|
|
|
|
|
var state = predicate();
|
|
|
|
|
while (!state)
|
|
|
|
|
{
|
|
|
|
|
if (DateTime.UtcNow - start > timeout)
|
|
|
|
|
{
|
|
|
|
|
throw new TimeoutException("Operation timed out.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Sleep(retryTime);
|
|
|
|
|
state = predicate();
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-10 07:55:36 +00:00
|
|
|
|
|
2023-05-31 11:15:41 +00:00
|
|
|
|
public static void Retry(Action action, string description)
|
2023-05-10 07:55:36 +00:00
|
|
|
|
{
|
2023-06-01 12:03:16 +00:00
|
|
|
|
Retry(action, TimeSpan.FromMinutes(1), description);
|
2023-05-10 07:55:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-31 11:15:41 +00:00
|
|
|
|
public static T Retry<T>(Func<T> action, string description)
|
2023-05-10 07:55:36 +00:00
|
|
|
|
{
|
2023-06-01 12:03:16 +00:00
|
|
|
|
return Retry(action, TimeSpan.FromMinutes(1), description);
|
2023-05-10 07:55:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-31 11:15:41 +00:00
|
|
|
|
public static void Retry(Action action, TimeSpan timeout, string description)
|
2023-05-10 07:55:36 +00:00
|
|
|
|
{
|
2023-06-01 12:03:16 +00:00
|
|
|
|
Retry(action, timeout, TimeSpan.FromSeconds(1), description);
|
2023-05-10 07:55:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-31 11:15:41 +00:00
|
|
|
|
public static T Retry<T>(Func<T> action, TimeSpan timeout, string description)
|
2023-05-10 07:55:36 +00:00
|
|
|
|
{
|
2023-06-01 12:03:16 +00:00
|
|
|
|
return Retry(action, timeout, TimeSpan.FromSeconds(1), description);
|
2023-05-10 07:55:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-31 11:15:41 +00:00
|
|
|
|
public static void Retry(Action action, TimeSpan timeout, TimeSpan retryTime, string description)
|
2023-05-10 07:55:36 +00:00
|
|
|
|
{
|
|
|
|
|
var start = DateTime.UtcNow;
|
|
|
|
|
var exceptions = new List<Exception>();
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
if (DateTime.UtcNow - start > timeout)
|
|
|
|
|
{
|
2023-05-31 11:15:41 +00:00
|
|
|
|
throw new TimeoutException($"Retry '{description}' of {timeout.TotalSeconds} seconds timed out.", new AggregateException(exceptions));
|
2023-05-10 07:55:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
action();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
exceptions.Add(ex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Sleep(retryTime);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-31 11:15:41 +00:00
|
|
|
|
public static T Retry<T>(Func<T> action, TimeSpan timeout, TimeSpan retryTime, string description)
|
2023-05-10 07:55:36 +00:00
|
|
|
|
{
|
|
|
|
|
var start = DateTime.UtcNow;
|
|
|
|
|
var exceptions = new List<Exception>();
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
if (DateTime.UtcNow - start > timeout)
|
|
|
|
|
{
|
2023-05-31 11:15:41 +00:00
|
|
|
|
throw new TimeoutException($"Retry '{description}' of {timeout.TotalSeconds} seconds timed out.", new AggregateException(exceptions));
|
2023-05-10 07:55:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return action();
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
exceptions.Add(ex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Sleep(retryTime);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-12 11:53:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|