< Summary

Information
Class: ProjectTemplate.Web.Services.BackgroundServiceRetryDelay
Assembly: ProjectTemplate.Web
File(s): /home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/src/ProjectTemplate.Web/Services/BackgroundServiceRetryDelay.cs
Line coverage
100%
Covered lines: 8
Uncovered lines: 0
Coverable lines: 8
Total lines: 44
Line coverage: 100%
Branch coverage
100%
Covered branches: 6
Total branches: 6
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Calculate(...)100%66100%

File(s)

/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/src/ProjectTemplate.Web/Services/BackgroundServiceRetryDelay.cs

#LineLine coverage
 1namespace ProjectTemplate.Web.Services;
 2
 3/// <summary>
 4/// Calculates the delay before a background service retries after consecutive failures.
 5/// </summary>
 6/// <remarks>
 7/// A fixed poll interval keeps a failing dependency under constant load and fills the log with one entry per cycle.
 8/// After a failure the delay doubles for each additional consecutive failure, up to a configured maximum, and returns
 9/// to the normal interval as soon as a cycle succeeds.
 10/// </remarks>
 11internal static class BackgroundServiceRetryDelay
 12{
 13    /// <summary>
 14    /// Calculates the delay before the next cycle.
 15    /// </summary>
 16    /// <param name="interval">The configured interval between successful cycles.</param>
 17    /// <param name="maximumRetryDelay">The maximum delay after consecutive failures.</param>
 18    /// <param name="consecutiveFailureCount">The number of consecutive failed cycles; zero after a success.</param>
 19    /// <returns>
 20    /// <paramref name="interval"/> when the previous cycle succeeded; otherwise the interval doubled once per
 21    /// additional consecutive failure, capped at <paramref name="maximumRetryDelay"/>.
 22    /// </returns>
 23    internal static TimeSpan Calculate(
 24        TimeSpan interval,
 25        TimeSpan maximumRetryDelay,
 26        int consecutiveFailureCount)
 27    {
 1028        ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(interval, TimeSpan.Zero);
 929        ArgumentOutOfRangeException.ThrowIfNegative(consecutiveFailureCount);
 30
 831        if (consecutiveFailureCount == 0)
 32        {
 133            return interval;
 34        }
 35
 736        TimeSpan cap = maximumRetryDelay > interval ? maximumRetryDelay : interval;
 37
 38        // Cap the exponent before multiplying so a long-running outage cannot overflow the calculation.
 739        int exponent = Math.Min(consecutiveFailureCount - 1, 16);
 740        double delayTicks = interval.Ticks * Math.Pow(2, exponent);
 41
 742        return delayTicks >= cap.Ticks ? cap : TimeSpan.FromTicks((long)delayTicks);
 43    }
 44}