perf(ui): shared KPI cache, live-cache-backed alarm summary, coalesced debug renders
This commit is contained in:
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user