gateway: alarm-RPC dispatcher seam (PRs A.6 + A.7)
Replaces the inline diagnostic strings in PR A.3's AcknowledgeAlarm + QueryActiveAlarms handlers with an IAlarmRpcDispatcher seam. - IAlarmRpcDispatcher (new) — gateway-side abstraction over the worker-RPC path that fronts AlarmClient.AlarmAckByGUID and the active-alarm walk. AcknowledgeAsync returns the AcknowledgeAlarmReply directly; QueryActiveAlarmsAsync yields an IAsyncEnumerable<ActiveAlarmSnapshot>. - NotWiredAlarmRpcDispatcher (new, default impl) — returns PROTOCOL_STATUS_OK with a structured worker-pending diagnostic on Acknowledge, yields an empty stream on QueryActiveAlarms. Same observable shape as PR A.3, but the integration seam is now in code instead of hardcoded inside the handler. - MxAccessGatewayService — handlers delegate to the dispatcher. Constructor accepts an optional IAlarmRpcDispatcher (default NotWiredAlarmRpcDispatcher); a future WorkerAlarmRpcDispatcher registration in DI swaps in the live worker-IPC routing without changing the public RPC surface. - 2 new dispatcher tests pin the not-wired contract; 279 → 281 total tests, all green. Worker-side dispatch (translating Acknowledge / QueryActiveAlarms to the IPC method that calls IMxAccessAlarmConsumer from PR A.5) is the dev-rig follow-up — it depends on validating the AVEVA GetAlarmChangesCompleted event subscription against a live alarm provider before pinning a wire format. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MxGateway.Contracts.Proto;
|
||||
|
||||
namespace MxGateway.Server.Sessions;
|
||||
|
||||
/// <summary>
|
||||
/// PR A.6 / A.7 — gateway-side dispatcher for the alarm-RPC surface.
|
||||
/// Bridges the public <c>AcknowledgeAlarm</c> + <c>QueryActiveAlarms</c>
|
||||
/// gRPC handlers to the worker process that hosts
|
||||
/// <c>IMxAccessAlarmConsumer</c>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Production implementations live in <c>WorkerAlarmRpcDispatcher</c>
|
||||
/// (this PR ships a not-yet-wired default that returns a clear
|
||||
/// worker-pending diagnostic) and route through the existing
|
||||
/// worker-pipe IPC. Tests inject a fake to exercise the gateway
|
||||
/// handler shape without spinning up a worker process.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The dispatcher is session-scoped: every call resolves the
|
||||
/// session and forwards to that session's worker. The handler
|
||||
/// constructs the <see cref="AcknowledgeAlarmReply"/> /
|
||||
/// <see cref="ActiveAlarmSnapshot"/> stream from the dispatcher's
|
||||
/// output without further translation.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public interface IAlarmRpcDispatcher
|
||||
{
|
||||
/// <summary>Forward an Acknowledge to the worker that owns the session.</summary>
|
||||
Task<AcknowledgeAlarmReply> AcknowledgeAsync(
|
||||
AcknowledgeAlarmRequest request,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>Walk active alarms on the worker that owns the session.</summary>
|
||||
IAsyncEnumerable<ActiveAlarmSnapshot> QueryActiveAlarmsAsync(
|
||||
QueryActiveAlarmsRequest request,
|
||||
CancellationToken cancellationToken);
|
||||
}
|
||||
Reference in New Issue
Block a user