refactor(worker): alarm consumers resolve the AckMsg item instead of acking

IMxAccessAlarmConsumer.ResolveAckTarget/ResolveAckTargetByName replace AcknowledgeByGuid/AcknowledgeByName. wnwrap maps Galaxy-provider alarms to <tag>.AckMsg and drops its inert parallel ack consumer; subtag resolves to the target's AckCommentSubtag and no longer advises or writes it; ISubtagAlarmSource.Write is removed. Does not build alone: AlarmDispatcher moves to the new API in the next commit.

Claude-Session: https://claude.ai/code/session_016J6isfcgqy4SB2RK3ZvFvT
This commit is contained in:
Joseph Doherty
2026-10-19 19:35:49 -04:00
parent 8199553734
commit 0d4b2aea2d
11 changed files with 238 additions and 452 deletions
@@ -72,10 +72,10 @@ public sealed class FailoverAlarmConsumerTests
}
/// <inheritdoc />
public int AcknowledgeByGuid(Guid g, string c, string a, string b, string d, string e) => 11;
public AlarmAckTarget ResolveAckTarget(Guid g) => AlarmAckTarget.For("primary.guid.AckMsg");
/// <inheritdoc />
public int AcknowledgeByName(string n, string p, string gr, string c, string a, string b, string d, string e) => 11;
public AlarmAckTarget ResolveAckTargetByName(string n, string p, string gr) => AlarmAckTarget.For("primary.name.AckMsg");
/// <inheritdoc />
public IReadOnlyList<MxAlarmSnapshotRecord> SnapshotActiveAlarms(out bool truncated)
@@ -122,10 +122,10 @@ public sealed class FailoverAlarmConsumerTests
public void PollOnce() { }
/// <inheritdoc />
public int AcknowledgeByGuid(Guid g, string c, string a, string b, string d, string e) => 22;
public AlarmAckTarget ResolveAckTarget(Guid g) => AlarmAckTarget.For("standby.guid.AckMsg");
/// <inheritdoc />
public int AcknowledgeByName(string n, string p, string gr, string c, string a, string b, string d, string e) => 22;
public AlarmAckTarget ResolveAckTargetByName(string n, string p, string gr) => AlarmAckTarget.For("standby.name.AckMsg");
/// <inheritdoc />
public IReadOnlyList<MxAlarmSnapshotRecord> SnapshotActiveAlarms(out bool truncated)
@@ -305,9 +305,9 @@ public sealed class FailoverAlarmConsumerTests
Assert.Equal(subscribeCountAfterSetup, primary.SubscribeCount);
}
/// <summary>Proves that acknowledgment calls delegate to whichever child (primary or standby) is currently active.</summary>
/// <summary>Proves that ack-target resolution delegates to whichever child (primary or standby) is currently active.</summary>
[Fact]
public void Acknowledge_DelegatesToActiveChild()
public void ResolveAckTarget_DelegatesToActiveChild()
{
FlakyPrimary primary = new FlakyPrimary { ThrowOnPoll = false };
StubStandby standby = new StubStandby();
@@ -316,18 +316,18 @@ public sealed class FailoverAlarmConsumerTests
sut.Subscribe(@"\\HOST\Galaxy!Area");
// Active = Primary → primary's sentinel value (11).
Assert.Equal(11, sut.AcknowledgeByGuid(Guid.NewGuid(), "c", "n", "node", "dom", "full"));
Assert.Equal(11, sut.AcknowledgeByName("a", "p", "g", "c", "n", "node", "dom", "full"));
// Active = Primary → primary's sentinel targets.
Assert.Equal("primary.guid.AckMsg", sut.ResolveAckTarget(Guid.NewGuid()).ItemAddress);
Assert.Equal("primary.name.AckMsg", sut.ResolveAckTargetByName("a", "p", "g").ItemAddress);
// Force a failover by failing the primary past threshold.
primary.ThrowOnPoll = true;
sut.PollOnce(); // threshold=1 → switch to Standby
Assert.Equal(AlarmProviderMode.Subtag, sut.Mode);
// Active = Standby → standby's sentinel value (22).
Assert.Equal(22, sut.AcknowledgeByGuid(Guid.NewGuid(), "c", "n", "node", "dom", "full"));
Assert.Equal(22, sut.AcknowledgeByName("a", "p", "g", "c", "n", "node", "dom", "full"));
// Active = Standby → standby's sentinel targets.
Assert.Equal("standby.guid.AckMsg", sut.ResolveAckTarget(Guid.NewGuid()).ItemAddress);
Assert.Equal("standby.name.AckMsg", sut.ResolveAckTargetByName("a", "p", "g").ItemAddress);
}
/// <summary>