fix(kpi-history): backlogTotal trend records the real site-backlog aggregate instead of a hardwired zero
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Kpi;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.HealthMonitoring.Kpi;
|
||||
|
||||
/// <summary>
|
||||
/// Central <see cref="IAuditBacklogProvider"/> — sums the latest per-site
|
||||
/// <c>SiteAuditBacklog.PendingCount</c> across the in-memory
|
||||
/// <see cref="ICentralHealthAggregator"/>, the same aggregate the live
|
||||
/// Health-dashboard "Audit" backlog tile shows
|
||||
/// (<c>AuditLogQueryService.GetKpiSnapshotAsync</c>).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Registered only on the central node (where the aggregator lives), so the
|
||||
/// <see cref="ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Kpi.IKpiSampleSource"/>
|
||||
/// backing the <c>backlogTotal</c> trend records the real backlog instead of the
|
||||
/// append-only repository's hardwired zero. Best-effort: sites with no report or
|
||||
/// a null <c>SiteAuditBacklog</c> contribute nothing.
|
||||
/// </remarks>
|
||||
public sealed class CentralHealthAuditBacklogProvider : IAuditBacklogProvider
|
||||
{
|
||||
private readonly ICentralHealthAggregator _aggregator;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CentralHealthAuditBacklogProvider"/> class.
|
||||
/// </summary>
|
||||
/// <param name="aggregator">The central health aggregator whose per-site latest reports carry the backlog.</param>
|
||||
public CentralHealthAuditBacklogProvider(ICentralHealthAggregator aggregator)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(aggregator);
|
||||
_aggregator = aggregator;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public long GetPendingBacklogTotal()
|
||||
{
|
||||
// Ported verbatim from AuditLogQueryService.GetKpiSnapshotAsync: a null
|
||||
// SiteAuditBacklog is "unknown" (contributes zero), and the `> 0` guard
|
||||
// ignores any defensive negative/zero value so the tile and the history
|
||||
// agree exactly.
|
||||
long backlog = 0;
|
||||
foreach (var state in _aggregator.GetAllSiteStates().Values)
|
||||
{
|
||||
var pending = state.LatestReport?.SiteAuditBacklog?.PendingCount;
|
||||
if (pending is > 0)
|
||||
{
|
||||
backlog += pending.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return backlog;
|
||||
}
|
||||
}
|
||||
@@ -63,6 +63,15 @@ public static class ServiceCollectionExtensions
|
||||
services.AddHostedService(sp => sp.GetRequiredService<CentralHealthAggregator>());
|
||||
services.AddHostedService<CentralHealthReportLoop>();
|
||||
|
||||
// Task 10 (arch-review 04): the central backlog aggregate for the Audit Log
|
||||
// KPI *history*. Only the central node runs the aggregator, so this seam is
|
||||
// registered here; the AuditLogKpiSampleSource resolves it (optional ctor
|
||||
// param) and records the real cross-site backlog instead of the append-only
|
||||
// repository's hardwired zero. Sites leave it unregistered → snapshot fallback.
|
||||
services.AddSingleton<
|
||||
Commons.Interfaces.Kpi.IAuditBacklogProvider,
|
||||
Kpi.CentralHealthAuditBacklogProvider>();
|
||||
|
||||
// "KPI History & Trends": per-site Site Health KPI sample source.
|
||||
// Reads the in-memory central aggregator (a singleton) rather than a
|
||||
// repository; registered Scoped to match the recorder's per-tick scope
|
||||
|
||||
Reference in New Issue
Block a user