sidecar: AahClientManagedAlarmEventWriter implements IAlarmEventWriter (PR C.1)
Fourth PR of the alarms-over-gateway epic (docs/plans/alarms-over-gateway.md). Independent of Tracks A and B — the sidecar slot defined in HistorianFrameHandler line 242 is unwired today; PR C.2 (next) flips it on in Program.cs. - AlarmHistorianWriteOutcome (sidecar-local, net48 — twin of Core.AlarmHistorian.HistorianWriteOutcome which is net10): Ack / RetryPlease / PermanentFail. - IAlarmHistorianWriteBackend abstraction so the SDK call can be faked in unit tests. - AahClientManagedAlarmEventWriter implements IAlarmEventWriter, delegates to the backend, maps Ack→true / Retry|Permanent→false for the IPC bool[] reply contract. Backend exception → whole batch RetryPlease (preserves the sender's queue across transients rather than dropping). Wrong-count return defends against a backend bug desyncing queue accounting. - SdkAlarmHistorianWriteBackend — production binding skeleton. Reports RetryPlease for every event and logs a structured diagnostic until PR D.1 pins the live aahClientManaged entry point against the dev rig. The sender's SqliteStoreAndForwardSink retains queued events, mirroring today's NullAlarmHistorianSink behaviour but with visible diagnostics instead of silent discard. - MapOutcome shared helper — pinned via theory tests so the D.1 swap can change the SDK call site without reshuffling the HRESULT → outcome mapping. Tests: - 6 writer tests — empty batch / single Ack / mixed Ack-Retry- Permanent-Ack ordering / backend-throw → RetryPlease batch / cancellation propagates / wrong-count defensive degrade. - 5 outcome theory cases — hresult 0 → Ack, malformed wins over hresult 0, comm error → Retry, unknown failure → Retry, malformed + comm → Permanent. - Full sidecar test suite: 48 passed (was 42; 6 new). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ZB.MOM.WW.OtOpcUa.Driver.Historian.Wonderware.Ipc;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.Driver.Historian.Wonderware.Backend
|
||||
{
|
||||
/// <summary>
|
||||
/// The actual aahClientManaged-bound writer. Extracted so unit tests can
|
||||
/// substitute a fake without touching the SDK; the production
|
||||
/// implementation lives in <see cref="SdkAlarmHistorianWriteBackend"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Implementations are responsible for connection management + cluster
|
||||
/// failover. The wrapping <see cref="AahClientManagedAlarmEventWriter"/>
|
||||
/// handles batch-level orchestration but delegates the per-event SDK call
|
||||
/// here so the unit tests can drive every documented MxStatus outcome
|
||||
/// without an installed AVEVA Historian.
|
||||
/// </remarks>
|
||||
public interface IAlarmHistorianWriteBackend
|
||||
{
|
||||
/// <summary>
|
||||
/// Persist the supplied events to the historian. Returns one outcome per
|
||||
/// input slot in the same order — must always return an array of the same
|
||||
/// length as <paramref name="events"/>.
|
||||
/// </summary>
|
||||
Task<AlarmHistorianWriteOutcome[]> WriteBatchAsync(
|
||||
AlarmHistorianEventDto[] events,
|
||||
CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user