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-06-01 14:28:34 +00:00
public static void WaitUntil ( Func < bool > predicate )
{
WaitUntil ( predicate , TimeSpan . FromMinutes ( 1 ) , TimeSpan . FromSeconds ( 1 ) ) ;
}
2023-04-17 14:28:07 +00:00
2023-09-22 08:02:16 +00:00
public static void WaitUntil ( Func < bool > predicate , TimeSpan timeout , TimeSpan retryDelay )
2023-04-17 14:28:07 +00:00
{
var start = DateTime . UtcNow ;
var state = predicate ( ) ;
while ( ! state )
{
if ( DateTime . UtcNow - start > timeout )
{
throw new TimeoutException ( "Operation timed out." ) ;
}
2023-09-22 08:02:16 +00:00
Sleep ( retryDelay ) ;
2023-04-17 14:28:07 +00:00
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-10-23 08:11:02 +00:00
Retry ( action , 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-10-23 08:11:02 +00:00
return Retry ( action , 1 , description ) ;
2023-05-10 07:55:36 +00:00
}
2023-10-23 08:11:02 +00:00
public static void Retry ( Action action , int maxRetries , string description )
2023-05-10 07:55:36 +00:00
{
2023-10-23 08:11:02 +00:00
Retry ( action , maxRetries , TimeSpan . FromSeconds ( 1 ) , description ) ;
2023-05-10 07:55:36 +00:00
}
2023-10-23 08:11:02 +00:00
public static T Retry < T > ( Func < T > action , int maxRetries , string description )
2023-05-10 07:55:36 +00:00
{
2023-10-23 08:11:02 +00:00
return Retry ( action , maxRetries , TimeSpan . FromSeconds ( 1 ) , description ) ;
2023-05-10 07:55:36 +00:00
}
2023-10-23 08:11:02 +00:00
public static void Retry ( Action action , int maxRetries , TimeSpan retryTime , string description )
2023-05-10 07:55:36 +00:00
{
var start = DateTime . UtcNow ;
2023-10-23 08:11:02 +00:00
var retries = 0 ;
2023-05-10 07:55:36 +00:00
var exceptions = new List < Exception > ( ) ;
while ( true )
{
2023-10-23 08:11:02 +00:00
if ( retries > maxRetries )
2023-05-10 07:55:36 +00:00
{
2023-10-23 08:11:02 +00:00
var duration = DateTime . UtcNow - start ;
throw new TimeoutException ( $"Retry '{description}' timed out after {maxRetries} tries over {Time.FormatDuration(duration)}." , new AggregateException ( exceptions ) ) ;
2023-05-10 07:55:36 +00:00
}
try
{
action ( ) ;
return ;
}
catch ( Exception ex )
{
exceptions . Add ( ex ) ;
2023-10-23 08:11:02 +00:00
retries + + ;
2023-05-10 07:55:36 +00:00
}
Sleep ( retryTime ) ;
}
}
2023-10-23 08:11:02 +00:00
public static T Retry < T > ( Func < T > action , int maxRetries , TimeSpan retryTime , string description )
2023-05-10 07:55:36 +00:00
{
var start = DateTime . UtcNow ;
2023-10-23 08:11:02 +00:00
var retries = 0 ;
2023-05-10 07:55:36 +00:00
var exceptions = new List < Exception > ( ) ;
while ( true )
{
2023-10-23 08:11:02 +00:00
if ( retries > maxRetries )
2023-05-10 07:55:36 +00:00
{
2023-10-23 08:11:02 +00:00
var duration = DateTime . UtcNow - start ;
throw new TimeoutException ( $"Retry '{description}' timed out after {maxRetries} tries over {Time.FormatDuration(duration)}." , new AggregateException ( exceptions ) ) ;
2023-05-10 07:55:36 +00:00
}
try
{
return action ( ) ;
}
catch ( Exception ex )
{
exceptions . Add ( ex ) ;
2023-10-23 08:11:02 +00:00
retries + + ;
2023-05-10 07:55:36 +00:00
}
Sleep ( retryTime ) ;
}
}
2023-04-12 11:53:55 +00:00
}
}