feat(site-runtime): stamp IsMesReportable on the Instance Actor alarm snapshot
Claude-Session: https://claude.ai/code/session_01Y5ef34iUUMjmwnMpL9xgmB
This commit is contained in:
@@ -51,6 +51,16 @@ public class InstanceActor : ReceiveActor
|
||||
private readonly Dictionary<string, AlarmState> _alarmStates = new();
|
||||
private readonly Dictionary<string, DateTimeOffset> _alarmTimestamps = new();
|
||||
private readonly Dictionary<string, int> _alarmPriorities = new();
|
||||
|
||||
/// <summary>
|
||||
/// Computed-alarm canonical name → the deployed <c>ResolvedAlarm.IsMesReportable</c>
|
||||
/// flag. Populated alongside <see cref="_alarmPriorities"/> when the Alarm Actor
|
||||
/// children are created and read back in <see cref="BuildAlarmStatesSnapshot"/>, which
|
||||
/// is the single place the flag is stamped — so a fired alarm (served from the retained
|
||||
/// event) and an unfired one (served from the bare fallback projection) cannot drift.
|
||||
/// Native conditions have no entry here and correctly resolve to false.
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, bool> _alarmMesReportable = new();
|
||||
private readonly Dictionary<string, IActorRef> _scriptActors = new();
|
||||
private readonly Dictionary<string, IActorRef> _alarmActors = new();
|
||||
private readonly Dictionary<string, IActorRef> _nativeAlarmActors = new();
|
||||
@@ -1568,7 +1578,16 @@ public class InstanceActor : ReceiveActor
|
||||
/// </summary>
|
||||
private List<AlarmStateChanged> BuildAlarmStatesSnapshot()
|
||||
{
|
||||
var states = _latestAlarmEvents.Values.ToList();
|
||||
// The MES-reportable flag is stamped HERE and nowhere else (not at the Alarm
|
||||
// Actor's emit sites), so the retained-event rows below and the fallback rows
|
||||
// that follow always agree on it. A native condition has no _alarmMesReportable
|
||||
// entry and is returned as-is (no record copy) — the default false is the intended
|
||||
// result, and native rows dominate this list on a busy binding.
|
||||
var states = _latestAlarmEvents.Values
|
||||
.Select(e => _alarmMesReportable.TryGetValue(e.AlarmName, out var mes) && mes
|
||||
? e with { IsMesReportable = true }
|
||||
: e)
|
||||
.ToList();
|
||||
|
||||
foreach (var name in _alarmActors.Keys)
|
||||
{
|
||||
@@ -1582,7 +1601,10 @@ public class InstanceActor : ReceiveActor
|
||||
name,
|
||||
_alarmStates.GetValueOrDefault(name, AlarmState.Normal),
|
||||
_alarmPriorities.GetValueOrDefault(name, 0),
|
||||
_alarmTimestamps.GetValueOrDefault(name, DateTimeOffset.UtcNow)));
|
||||
_alarmTimestamps.GetValueOrDefault(name, DateTimeOffset.UtcNow))
|
||||
{
|
||||
IsMesReportable = _alarmMesReportable.GetValueOrDefault(name)
|
||||
});
|
||||
}
|
||||
|
||||
// A native binding is "already represented" if any retained event carries its
|
||||
@@ -1980,6 +2002,7 @@ public class InstanceActor : ReceiveActor
|
||||
var actorRef = Context.ActorOf(props, $"alarm-{alarm.CanonicalName}");
|
||||
_alarmActors[alarm.CanonicalName] = actorRef;
|
||||
_alarmPriorities[alarm.CanonicalName] = alarm.PriorityLevel;
|
||||
_alarmMesReportable[alarm.CanonicalName] = alarm.IsMesReportable;
|
||||
_alarmTimestamps[alarm.CanonicalName] = DateTimeOffset.UtcNow;
|
||||
RouteChild(actorRef, TriggerRouting.ForAlarm(alarm.TriggerType, alarm.TriggerConfiguration));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user