feat(alarms): feed-level snapshot_status truncation frame on StreamAlarms
This commit is contained in:
+31
-1
@@ -94,7 +94,7 @@ An accepted gRPC command payload can still be too large for the worker pipe: the
|
||||
|
||||
### `StreamAlarms`
|
||||
|
||||
`StreamAlarms` is a server-streaming, **session-less** RPC that attaches to the gateway's central alarm feed. The handler delegates to `IGatewayAlarmService.StreamAsync`. The stream opens with one `AlarmFeedMessage` carrying an `active_alarm` per currently-active alarm (the ConditionRefresh snapshot), then a single `snapshot_complete`, then a `transition` for every subsequent raise / acknowledge / clear. It is served by the always-on `GatewayAlarmMonitor`, which owns a single gateway-managed worker session and fans out to every attached client — clients no longer open a session of their own. `alarm_filter_prefix`, when set, scopes the stream to a sub-tree.
|
||||
`StreamAlarms` is a server-streaming, **session-less** RPC that attaches to the gateway's central alarm feed. The handler delegates to `IGatewayAlarmService.StreamAsync`. The stream opens with a `provider_status` and a `snapshot_status` `AlarmFeedMessage` (the current provider mode and snapshot-completeness verdict), then one `AlarmFeedMessage` carrying an `active_alarm` per currently-active alarm (the ConditionRefresh snapshot), then a single `snapshot_complete`, then a `transition` for every subsequent raise / acknowledge / clear — interleaved with a further `provider_status` on each failover/failback and a further `snapshot_status` on each change of the truncation verdict. It is served by the always-on `GatewayAlarmMonitor`, which owns a single gateway-managed worker session and fans out to every attached client — clients no longer open a session of their own. `alarm_filter_prefix`, when set, scopes the stream to a sub-tree.
|
||||
|
||||
### `QueryActiveAlarms`
|
||||
|
||||
@@ -119,6 +119,36 @@ The gateway emits `provider_status` once when a client first subscribes
|
||||
and again on every failover or failback. A late-joining client therefore
|
||||
always learns the current provider mode without waiting for the next switch.
|
||||
|
||||
#### Snapshot completeness on the alarm feed
|
||||
|
||||
`AlarmFeedMessage` has a fifth `payload` case, `snapshot_status`, carrying
|
||||
an `AlarmSnapshotStatus` message:
|
||||
|
||||
```protobuf
|
||||
message AlarmSnapshotStatus {
|
||||
bool truncated = 1; // the cached active set may be missing alarms
|
||||
}
|
||||
```
|
||||
|
||||
It is the feed-level twin of the per-record
|
||||
`ActiveAlarmSnapshot.from_truncated_snapshot` flag: `truncated` is true while the
|
||||
monitor's cached active-alarm set derives from a capped worker fetch. Read it as
|
||||
"this set may be incomplete", never as a statement about record fidelity — that
|
||||
is what `degraded` / `source_provider` mean, and the two are independent.
|
||||
|
||||
Emission mirrors `provider_status` but with one ordering rule of its own. The
|
||||
gateway emits `snapshot_status` once when a client subscribes, **after** the
|
||||
open-time `provider_status` and **before** the cached `active_alarm` frames, so a
|
||||
consumer applying the snapshot as it streams has the completeness caveat in hand
|
||||
while it applies it. The open-time frame is unconditional — an explicit
|
||||
`truncated = false` is what distinguishes a complete set from a gateway that
|
||||
never sends the frame. Afterwards it is emitted only on a *change* of verdict:
|
||||
when a reconcile flips the verdict either way, and when a monitor restart drops a
|
||||
truncated verdict with the cache generation it describes (feed subscribers
|
||||
outlive the monitor's worker session, so they see that clear). Clients that do
|
||||
not know the case see an unset `payload` oneof and ignore the message, exactly as
|
||||
before.
|
||||
|
||||
`AlarmProviderMode` is an enum with three values:
|
||||
|
||||
| Value | Meaning |
|
||||
|
||||
Reference in New Issue
Block a user