< Summary - Heimdall API

Information
Class: ArturRios.Heimdall.WebApi.Monitoring.ReadinessCache
Assembly: ArturRios.Heimdall.WebApi
File(s): /home/ci/agent/workspace/heimdall-api-docs_main/app/src/Presentation/ArturRios.Heimdall.WebApi/Monitoring/ReadinessCache.cs
Line coverage
100%
Covered lines: 10
Uncovered lines: 0
Coverable lines: 10
Total lines: 39
Line coverage: 100%
Branch coverage
100%
Covered branches: 4
Total branches: 4
Branch coverage: 100%
Method coverage
100%
Covered methods: 3
Fully covered methods: 3
Total methods: 3
Method coverage: 100%
Full method coverage: 100%

Metrics

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

File(s)

/home/ci/agent/workspace/heimdall-api-docs_main/app/src/Presentation/ArturRios.Heimdall.WebApi/Monitoring/ReadinessCache.cs

#LineLine coverage
 1namespace ArturRios.Heimdall.WebApi.Monitoring;
 2
 3/// <summary>
 4///     Holds the readiness answer for <see cref="Window">a few seconds</see>, so the anonymous probe costs
 5///     the database one read per window however often it is called (#215).
 6/// </summary>
 7/// <remarks>
 8///     A singleton. Callers that arrive while a check is in flight, or within the window after it, share
 9///     its result, so the window expiring does not release a herd of reads at once. The unhealthy answer is
 10///     held too: while the database is down, a flood of probes writes no further read, stack trace or
 11///     Warning until the window ends. Five seconds is shorter than the Compose probe's interval, so the
 12///     probe still sees every change.
 13/// </remarks>
 1514public class ReadinessCache(TimeProvider clock)
 15{
 16    /// <summary>How long an answer is reused.</summary>
 117    public static readonly TimeSpan Window = TimeSpan.FromSeconds(5);
 18
 1519    private readonly object _gate = new();
 20    private Task<bool>? _current;
 21    private DateTimeOffset _startedAt;
 22
 23    /// <summary>The cached answer, or the result of <paramref name="check" /> when there is none current.</summary>
 24    public Task<bool> IsReadyAsync(Func<Task<bool>> check)
 25    {
 2726        lock (_gate)
 27        {
 2728            var now = clock.GetUtcNow();
 29
 2730            if (_current is null || now - _startedAt >= Window)
 31            {
 732                _current = check();
 733                _startedAt = now;
 34            }
 35
 2736            return _current;
 37        }
 2738    }
 39}