refactor(deployment): move PendingUpdatesCache to DeploymentManager so the CLI shares it (ScadaBridge#91)
`health pending-updates` (#63) called IPendingUpdatesEvaluator.EvaluateAsync directly from ManagementActor because the cache lived in CentralUI, so every CLI call was a full uncached fleet flatten. IPendingUpdatesCache/PendingUpdatesCache now live in DeploymentManager.PendingUpdates and are registered by AddDeploymentManager; the SingleFlightMemo<T> primitive moves to Commons.Caching (public) so both CentralUI's KPI / alarm-summary caches and DeploymentManager can use it. HandleGetPendingUpdates reads the shared cache; the UI circuits and the CLI now share one memo per node. Tests: ManagementActor repeated-calls test (fails against the direct evaluator call: 2 evaluations instead of 1), AddDeploymentManager singleton-registration test; the cache and memo tests move with their types. (ScadaBridge#91) Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
This commit is contained in:
@@ -551,14 +551,20 @@ the evaluator swallows an exception: a faulted evaluation propagates so the
|
||||
cache's single-flight memo discards the flight and the Central UI renders the
|
||||
aggregate as unavailable, rather than manufacturing a false "up to date".
|
||||
|
||||
The Central UI holds the snapshot behind a process-wide singleton
|
||||
`IPendingUpdatesCache` (`PendingUpdatesCache`, mirroring `KpiSnapshotCache`): one
|
||||
The snapshot is held behind a process-wide singleton `IPendingUpdatesCache`
|
||||
(`PendingUpdatesCache`, `DeploymentManager.PendingUpdates`, registered by
|
||||
`AddDeploymentManager`, mirroring the Central UI's `KpiSnapshotCache`). It lives
|
||||
here rather than in CentralUI so the Central UI circuits **and** the management
|
||||
API's `GetPendingUpdatesCommand` (CLI `health pending-updates`) share one memo
|
||||
(Gitea #91 — before, every CLI call ran a full uncached flatten). It is one
|
||||
`SingleFlightMemo<PendingUpdatesSnapshot>` keyed by
|
||||
`ScadaBridge:DeploymentManager:PendingUpdatesCacheTtl` (default 60 s, validated
|
||||
positive by `DeploymentManagerOptionsValidator`), each flight running the
|
||||
evaluator in its own DI scope. However many Blazor circuits poll
|
||||
evaluator in its own DI scope (the primitive, `SingleFlightMemo<T>`, lives in
|
||||
Commons `Caching`). However many Blazor circuits or CLI calls hit
|
||||
`GetAsync(forceRefresh)`, the fleet is flattened **at most once per TTL**, and not
|
||||
at all when no Deployer/Admin circuit is open. See
|
||||
at all when nobody asks. A deployment that finishes on this node drops the memo
|
||||
at once; one run through the peer central clears within the TTL. See
|
||||
`docs/plans/2026-09-14-pending-updates-design.md` for the full design, including
|
||||
the Sites-page badge/re-check UI and the rail-footer indicator
|
||||
(Component-CentralUI.md → *Site & Data Connection Management* and *Technology*).
|
||||
|
||||
@@ -227,7 +227,7 @@ The two-person authorization workflow for writes through the MxAccess Gateway. B
|
||||
|
||||
- **GetHealthSummary**: Query current health status of all sites.
|
||||
- **GetSiteHealth**: Query detailed health for a specific site.
|
||||
- **GetPendingUpdates**: Fleet-wide pending-updates counts (stale instances / sites with stale artifacts) with a per-site breakdown. Deployer role; site-scoped callers see only their permitted sites (Gitea #63).
|
||||
- **GetPendingUpdates**: Fleet-wide pending-updates counts (stale instances / sites with stale artifacts) with a per-site breakdown. Deployer role; site-scoped callers see only their permitted sites (Gitea #63). Served from the same process-wide `IPendingUpdatesCache` the Central UI reads, so repeated calls inside the cache TTL cost one fleet flatten (Gitea #91).
|
||||
|
||||
### Remote Queries
|
||||
|
||||
|
||||
Reference in New Issue
Block a user