< Summary

Information
Class: ProjectTemplate.Web.Diagnostics.RateLimitingFallbackWarningThrottle
Assembly: ProjectTemplate.Web
File(s): /home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/src/ProjectTemplate.Web/Diagnostics/RateLimitingFallbackWarningThrottle.cs
Line coverage
100%
Covered lines: 20
Uncovered lines: 0
Coverable lines: 20
Total lines: 64
Line coverage: 100%
Branch coverage
100%
Covered branches: 4
Total branches: 4
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
.ctor(...)100%11100%
TryAcquire(...)100%44100%

File(s)

/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/src/ProjectTemplate.Web/Diagnostics/RateLimitingFallbackWarningThrottle.cs

#LineLine coverage
 1namespace ProjectTemplate.Web.Diagnostics;
 2
 3/// <summary>
 4/// Limits how often the rate-limiting unknown-client fallback warning is written, while counting the
 5/// occurrences that were suppressed between warnings.
 6/// </summary>
 7/// <remarks>
 8/// The fallback path runs on every affected request. Without throttling, a deployment where
 9/// <c>RemoteIpAddress</c> is never available would write one warning per request.
 10/// </remarks>
 11internal sealed class RateLimitingFallbackWarningThrottle
 12{
 13    /// <summary>
 14    /// The default minimum interval between fallback warnings.
 15    /// </summary>
 116    internal static readonly TimeSpan DefaultInterval = TimeSpan.FromMinutes(1);
 17
 18    private readonly TimeProvider _timeProvider;
 19    private readonly long _intervalTimestampTicks;
 10920    private long _nextWarningTimestamp = long.MinValue;
 21    private long _suppressedCount;
 22
 23    /// <summary>
 24    /// Initializes a new instance of the <see cref="RateLimitingFallbackWarningThrottle"/> class.
 25    /// </summary>
 26    /// <param name="timeProvider">The time source used to measure the warning interval.</param>
 27    /// <param name="interval">The minimum interval between warnings. Must be greater than zero.</param>
 10928    internal RateLimitingFallbackWarningThrottle(TimeProvider timeProvider, TimeSpan interval)
 29    {
 10930        ArgumentNullException.ThrowIfNull(timeProvider);
 10931        ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(interval, TimeSpan.Zero);
 32
 10833        _timeProvider = timeProvider;
 10834        _intervalTimestampTicks = checked((long)(interval.TotalSeconds * timeProvider.TimestampFrequency));
 10835    }
 36
 37    /// <summary>
 38    /// Determines whether a fallback warning may be written now.
 39    /// </summary>
 40    /// <param name="suppressedCount">
 41    /// When this method returns <see langword="true"/>, the number of warnings suppressed since the previous
 42    /// warning; otherwise zero.
 43    /// </param>
 44    /// <returns><see langword="true"/> when the caller should write the warning; otherwise <see langword="false"/>.</re
 45    internal bool TryAcquire(out long suppressedCount)
 46    {
 10847        long now = _timeProvider.GetTimestamp();
 10848        long nextWarningTimestamp = Interlocked.Read(ref _nextWarningTimestamp);
 49
 10850        if (now >= nextWarningTimestamp &&
 10851            Interlocked.CompareExchange(
 10852                ref _nextWarningTimestamp,
 10853                now + _intervalTimestampTicks,
 10854                nextWarningTimestamp) == nextWarningTimestamp)
 55        {
 7256            suppressedCount = Interlocked.Exchange(ref _suppressedCount, 0);
 7257            return true;
 58        }
 59
 3660        _ = Interlocked.Increment(ref _suppressedCount);
 3661        suppressedCount = 0;
 3662        return false;
 63    }
 64}