1a2856526a
Comments described the *history* of how the code arrived (phase numbers, wave IDs, review IDs, dated TODOs) instead of what it does today. That scaffolding rotted as the codebase evolved. Cleaned 60 source files + .gitignore; behaviour unchanged (387/387 tests still pass). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
58 lines
2.4 KiB
C#
58 lines
2.4 KiB
C#
namespace Mbproxy;
|
|
|
|
/// <summary>
|
|
/// Service-wide counters for the mbproxy host. Tracks reload accept/reject counts and
|
|
/// timestamps so the status page can surface them without coupling to the reconciler.
|
|
///
|
|
/// <para>Constructed once at DI startup and shared as a singleton. All writes are via
|
|
/// dedicated methods that use <see cref="Interlocked"/> so reads from the status page
|
|
/// are always coherent without locking.</para>
|
|
/// </summary>
|
|
public sealed class ServiceCounters
|
|
{
|
|
// LastReloadUtc: stored as ticks-since-epoch via Interlocked.Exchange.
|
|
// 0 = "never reloaded". DateTimeOffset.MinValue.UtcTicks works as the sentinel
|
|
// but 0 is simpler. DateTimeOffset.UtcNow.UtcTicks is always > 0 after 1970.
|
|
private long _lastReloadUtcTicks; // 0 = never; Interlocked
|
|
private int _reloadAppliedCount; // Interlocked
|
|
private int _reloadRejectedCount; // Interlocked
|
|
|
|
/// <summary>Instant at which this service instance was constructed (service start proxy).</summary>
|
|
public DateTimeOffset StartedAtUtc { get; } = DateTimeOffset.UtcNow;
|
|
|
|
/// <summary>
|
|
/// UTC timestamp of the last successfully applied hot-reload, or <c>null</c> if no
|
|
/// reload has been accepted since the service started.
|
|
/// </summary>
|
|
public DateTimeOffset? LastReloadUtc
|
|
{
|
|
get
|
|
{
|
|
long ticks = Interlocked.Read(ref _lastReloadUtcTicks);
|
|
return ticks == 0 ? null : new DateTimeOffset(ticks, TimeSpan.Zero);
|
|
}
|
|
}
|
|
|
|
/// <summary>Total number of configuration reloads accepted since service start.</summary>
|
|
public int ReloadAppliedCount
|
|
=> Interlocked.CompareExchange(ref _reloadAppliedCount, 0, 0);
|
|
|
|
/// <summary>Total number of configuration reloads rejected since service start.</summary>
|
|
public int ReloadRejectedCount
|
|
=> Interlocked.CompareExchange(ref _reloadRejectedCount, 0, 0);
|
|
|
|
/// <summary>
|
|
/// Records one accepted reload. Bumps <see cref="ReloadAppliedCount"/> and updates
|
|
/// <see cref="LastReloadUtc"/>.
|
|
/// </summary>
|
|
public void RecordReloadApplied(DateTimeOffset timestamp)
|
|
{
|
|
Interlocked.Increment(ref _reloadAppliedCount);
|
|
Interlocked.Exchange(ref _lastReloadUtcTicks, timestamp.UtcTicks);
|
|
}
|
|
|
|
/// <summary>Bumps <see cref="ReloadRejectedCount"/>.</summary>
|
|
public void RecordReloadRejected()
|
|
=> Interlocked.Increment(ref _reloadRejectedCount);
|
|
}
|