< Summary

Information
Class: ArturRios.Util.FlowControl.Waiter.JitteredWaiter
Assembly: ArturRios.Util
File(s): D:\Repositories\dotnet-util\src\FlowControl\Waiter\JitteredWaiter.cs
Line coverage
100%
Covered lines: 18
Uncovered lines: 0
Coverable lines: 18
Total lines: 50
Line coverage: 100%
Branch coverage
100%
Covered branches: 4
Total branches: 4
Branch coverage: 100%
Method coverage
100%
Covered methods: 5
Fully covered methods: 4
Total methods: 5
Method coverage: 100%
Full method coverage: 80%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_MaxRetryCount()100%11100%
get_Count()100%11100%
get_CanRetry()100%11100%
Wait()100%44100%

File(s)

D:\Repositories\dotnet-util\src\FlowControl\Waiter\JitteredWaiter.cs

#LineLine coverage
 1namespace ArturRios.Util.FlowControl.Waiter;
 2
 3/// <summary>
 4/// Implements an exponential backoff waiting strategy with jitter to reduce contention.
 5/// </summary>
 6/// <remarks>
 7/// Wait times grow exponentially (2^n seconds base minus a fixed delay) and a random jitter is added.
 8/// Call <see cref="Wait"/> before each retry attempt until <see cref="CanRetry"/> is false.
 9/// </remarks>
 10/// <param name="maxRetryCount">Maximum number of retries allowed.</param>
 611public class JitteredWaiter(int maxRetryCount)
 12{
 13    private const int FixedWaitDelay = 500;
 14
 15    /// <summary>
 16    /// Maximum number of retries permitted.
 17    /// </summary>
 2218    public int MaxRetryCount { get; } = maxRetryCount;
 19
 3620    private int Count { get; set; }
 21
 22    /// <summary>
 23    /// Indicates whether another retry attempt can be performed.
 24    /// </summary>
 425    public bool CanRetry => Count < MaxRetryCount;
 26
 27    /// <summary>
 28    /// Asynchronously waits based on the current retry attempt using exponential backoff with jitter.
 29    /// </summary>
 30    /// <exception cref="MaxRetriesReachedException">Thrown when called more times than <see cref="MaxRetryCount"/>.</ex
 31    public async Task Wait()
 1232    {
 1233        if (Count >= MaxRetryCount)
 234        {
 235            throw new MaxRetriesReachedException();
 36        }
 37
 1038        var currentRetryAttempt = Count++;
 39
 1040        if (currentRetryAttempt == 0)
 541        {
 542            await Task.Delay(FixedWaitDelay);
 543        }
 44        else
 545        {
 546            var backoffPeriodMs = Convert.ToInt32(Math.Pow(2, currentRetryAttempt) * 1000) - FixedWaitDelay;
 547            await Task.Delay(FixedWaitDelay + backoffPeriodMs / 2 + new System.Random().Next(0, backoffPeriodMs / 2));
 548        }
 1049    }
 50}