perf(ui): shared KPI cache, live-cache-backed alarm summary, coalesced debug renders

This commit is contained in:
Joseph Doherty
2026-08-14 20:53:38 -04:00
parent ee193cd2bb
commit 8c0b36b2fa
19 changed files with 1554 additions and 64 deletions
@@ -0,0 +1,70 @@
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Notification;
using ZB.MOM.WW.ScadaBridge.Commons.Types;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Services;
/// <summary>
/// Process-level memoized point-in-time KPI snapshots shared by every Blazor circuit on
/// this node (arch-review WP2.4, finding #8 — the per-circuit polling half).
/// <para>
/// Every KPI here is a <em>global, point-in-time aggregate</em>: it does not vary by user,
/// site scope, or role, so N circuits asking for it inside one refresh window are asking
/// the identical question. Without memoization, ten Health dashboards meant ten Asks →
/// ten aggregate SQL round trips every ten seconds. Each accessor is independently
/// memoized with a short TTL and single-flight production, so the fleet costs ONE round
/// trip per KPI per window regardless of viewer count.
/// </para>
/// <para>
/// Faults are never memoized: a failed query is re-attempted by the next caller, and the
/// caller still sees the exception exactly as it would from a direct query — the pages'
/// existing per-tile "unavailable" degradation is unchanged.
/// </para>
/// </summary>
public interface IKpiSnapshotCache
{
/// <summary>Global Notification Outbox KPIs (queue depth, stuck, parked, delivered-last-interval).</summary>
/// <param name="forceRefresh">Bypass a still-fresh value (operator "Refresh"); an in-flight round is still joined.</param>
/// <param name="cancellationToken">Cancels this caller's wait, never the shared flight.</param>
/// <returns>The memoized notification KPI response.</returns>
Task<NotificationKpiResponse> GetNotificationKpisAsync(
bool forceRefresh = false, CancellationToken cancellationToken = default);
/// <summary>Per-source-site Notification Outbox KPI breakdown.</summary>
/// <param name="forceRefresh">Bypass a still-fresh value; an in-flight round is still joined.</param>
/// <param name="cancellationToken">Cancels this caller's wait, never the shared flight.</param>
/// <returns>The memoized per-site notification KPI response.</returns>
Task<PerSiteNotificationKpiResponse> GetPerSiteNotificationKpisAsync(
bool forceRefresh = false, CancellationToken cancellationToken = default);
/// <summary>Per-node Notification Outbox KPI breakdown (grouped by <c>SourceNode</c>).</summary>
/// <param name="forceRefresh">Bypass a still-fresh value; an in-flight round is still joined.</param>
/// <param name="cancellationToken">Cancels this caller's wait, never the shared flight.</param>
/// <returns>The memoized per-node notification KPI response.</returns>
Task<PerNodeNotificationKpiResponse> GetPerNodeNotificationKpisAsync(
bool forceRefresh = false, CancellationToken cancellationToken = default);
/// <summary>Global Site Call Audit KPIs (buffered, stuck, parked).</summary>
/// <param name="forceRefresh">Bypass a still-fresh value; an in-flight round is still joined.</param>
/// <param name="cancellationToken">Cancels this caller's wait, never the shared flight.</param>
/// <returns>The memoized site call KPI response.</returns>
Task<SiteCallKpiResponse> GetSiteCallKpisAsync(
bool forceRefresh = false, CancellationToken cancellationToken = default);
/// <summary>Per-node Site Call Audit KPI breakdown (grouped by <c>SourceNode</c>).</summary>
/// <param name="forceRefresh">Bypass a still-fresh value; an in-flight round is still joined.</param>
/// <param name="cancellationToken">Cancels this caller's wait, never the shared flight.</param>
/// <returns>The memoized per-node site call KPI response.</returns>
Task<PerNodeSiteCallKpiResponse> GetPerNodeSiteCallKpisAsync(
bool forceRefresh = false, CancellationToken cancellationToken = default);
/// <summary>
/// Audit Log KPI snapshot (1h volume + error rate over the central <c>AuditLog</c> table,
/// plus the summed per-site backlog).
/// </summary>
/// <param name="forceRefresh">Bypass a still-fresh value; an in-flight round is still joined.</param>
/// <param name="cancellationToken">Cancels this caller's wait, never the shared flight.</param>
/// <returns>The memoized audit KPI snapshot.</returns>
Task<AuditLogKpiSnapshot> GetAuditKpiSnapshotAsync(
bool forceRefresh = false, CancellationToken cancellationToken = default);
}