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
2023-12-20 14:56:03 +00:00
public static void Wait ( Task task )
{
task . Wait ( ) ;
}
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
2023-11-17 13:51:32 +00:00
public static TimeSpan ParseTimespan ( string span )
{
span = span . Replace ( " " , "" ) . Replace ( "," , "" ) ;
var result = TimeSpan . Zero ;
var number = "" ;
foreach ( var c in span )
{
if ( char . IsNumber ( c ) ) number + = c ;
else
{
var value = Convert . ToInt32 ( number ) ;
number = "" ;
if ( c = = 'd' ) result + = TimeSpan . FromDays ( value ) ;
else if ( c = = 'h' ) result + = TimeSpan . FromHours ( value ) ;
else if ( c = = 'm' ) result + = TimeSpan . FromMinutes ( value ) ;
else if ( c = = 's' ) result + = TimeSpan . FromSeconds ( value ) ;
else throw new Exception ( "Unknown time modifier: " + c ) ;
}
}
if ( ! string . IsNullOrEmpty ( number ) )
{
var value = Convert . ToInt32 ( number ) ;
result + = TimeSpan . FromSeconds ( value ) ;
}
return result ;
}
2024-04-14 07:17:25 +00:00
public static void WaitUntil ( Func < bool > predicate , string msg )
2023-06-01 14:28:34 +00:00
{
2024-04-14 07:17:25 +00:00
WaitUntil ( predicate , TimeSpan . FromMinutes ( 1 ) , TimeSpan . FromSeconds ( 1 ) , msg ) ;
2023-06-01 14:28:34 +00:00
}
2023-04-17 14:28:07 +00:00
2024-04-14 07:17:25 +00:00
public static void WaitUntil ( Func < bool > predicate , TimeSpan timeout , TimeSpan retryDelay , string msg )
2023-04-17 14:28:07 +00:00
{
var start = DateTime . UtcNow ;
2024-04-14 07:17:25 +00:00
var tries = 1 ;
2023-04-17 14:28:07 +00:00
var state = predicate ( ) ;
while ( ! state )
{
2024-04-14 07:17:25 +00:00
var duration = DateTime . UtcNow - start ;
if ( duration > timeout )
2023-04-17 14:28:07 +00:00
{
2024-04-14 07:17:25 +00:00
throw new TimeoutException ( $"Operation timed out after {tries} tries over (total) {FormatDuration(duration)}. '{msg}'" ) ;
2023-04-17 14:28:07 +00:00
}
2023-09-22 08:02:16 +00:00
Sleep ( retryDelay ) ;
2023-04-17 14:28:07 +00:00
state = predicate ( ) ;
2024-04-14 07:17:25 +00:00
tries + + ;
2023-04-17 14:28:07 +00:00
}
}
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-11-12 10:24:58 +00:00
Retry ( action , maxRetries , TimeSpan . FromSeconds ( 5 ) , 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-11-12 10:24:58 +00:00
return Retry ( action , maxRetries , TimeSpan . FromSeconds ( 5 ) , 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
}
}