< Summary

Information
Class: ArturRios.Util.FlowControl.Retry
Assembly: ArturRios.Util
File(s): D:\Repositories\dotnet-util\src\FlowControl\Retry.cs
Line coverage
90%
Covered lines: 40
Uncovered lines: 4
Coverable lines: 44
Total lines: 102
Line coverage: 90.9%
Branch coverage
75%
Covered branches: 6
Total branches: 8
Branch coverage: 75%
Method coverage
100%
Covered methods: 5
Fully covered methods: 1
Total methods: 5
Method coverage: 100%
Full method coverage: 20%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_New()100%11100%
MaxAttempts(...)100%11100%
DelayMilliseconds(...)100%11100%
Execute(...)75%4488.88%
Execute(...)75%4488.23%

File(s)

D:\Repositories\dotnet-util\src\FlowControl\Retry.cs

#LineLine coverage
 1namespace ArturRios.Util.FlowControl;
 2
 3/// <summary>
 4/// Provides a simple retry mechanism for executing actions or functions with optional fixed delay between attempts.
 5/// </summary>
 6/// <remarks>
 7/// Configure using <see cref="MaxAttempts"/> and <see cref="DelayMilliseconds"/> then call <see cref="Execute(Action)"/
 8/// Exceptions are rethrown after the maximum number of attempts has been exhausted.
 9/// </remarks>
 10public class Retry
 11{
 12    private int _delayMilliseconds;
 13    private int _maxAttempts;
 14
 15    /// <summary>
 16    /// Creates a new <see cref="Retry"/> instance. Syntactic sugar for <c>new Retry()</c>.
 17    /// </summary>
 218    public static Retry New => new();
 19
 20    /// <summary>
 21    /// Sets the maximum number of retry attempts before giving up and rethrowing the last exception.
 22    /// </summary>
 23    /// <param name="maxAttempts">Number of attempts; must be greater than zero.</param>
 24    /// <returns>The configured <see cref="Retry"/> instance.</returns>
 25    public Retry MaxAttempts(int maxAttempts)
 226    {
 227        _maxAttempts = maxAttempts;
 28
 229        return this;
 230    }
 31
 32    /// <summary>
 33    /// Sets a fixed delay (in milliseconds) to wait after a failed attempt before retrying.
 34    /// </summary>
 35    /// <param name="delayMilliseconds">Delay duration in milliseconds.</param>
 36    /// <returns>The configured <see cref="Retry"/> instance.</returns>
 37    public Retry DelayMilliseconds(int delayMilliseconds)
 238    {
 239        _delayMilliseconds = delayMilliseconds;
 40
 241        return this;
 242    }
 43
 44    /// <summary>
 45    /// Executes an <see cref="Action"/> applying the configured retry strategy.
 46    /// </summary>
 47    /// <param name="action">The action to execute.</param>
 48    /// <exception cref="Exception">Rethrows the last exception encountered after all retries fail.</exception>
 49    public void Execute(Action action)
 150    {
 351        while (true)
 352        {
 53            try
 354            {
 355                action();
 156                break;
 57            }
 258            catch
 259            {
 260                if (_maxAttempts-- <= 0)
 061                {
 062                    throw;
 63                }
 64
 265                if (_delayMilliseconds > 0)
 266                {
 267                    Thread.Sleep(_delayMilliseconds);
 268                }
 269            }
 270        }
 171    }
 72
 73    /// <summary>
 74    /// Executes a function applying the configured retry strategy and returns its result.
 75    /// </summary>
 76    /// <typeparam name="T">Return type of the function.</typeparam>
 77    /// <param name="func">The function to invoke.</param>
 78    /// <returns>The value returned by <paramref name="func"/>.</returns>
 79    /// <exception cref="Exception">Rethrows the last exception encountered after all retries fail.</exception>
 80    public T Execute<T>(Func<T> func)
 181    {
 382        while (true)
 383        {
 84            try
 385            {
 386                return func();
 87            }
 288            catch
 289            {
 290                if (_maxAttempts-- <= 0)
 091                {
 092                    throw;
 93                }
 94
 295                if (_delayMilliseconds > 0)
 296                {
 297                    Thread.Sleep(_delayMilliseconds);
 298                }
 299            }
 2100        }
 1101    }
 102}