4e492e6550
mxaccessgw answers AcknowledgeAlarm OK both when the AckMsg write was applied and when it was only sent (no OnWriteComplete; the reply then carries a diagnostic). EvaluateReply treated both as success, so the H6 live gate saw a condition go Acknowledged while Galaxy never applied it. - EvaluateReply returns Applied (no diagnostic) or Unconfirmed (diagnostic) and logs the gateway diagnostic on every branch that carries one. - GalaxyAckConfirmationTracker watches the alarm feed from before the RPC and, for an unconfirmed reply, waits up to AlarmAck.ConfirmTimeoutMs (default 10 s, 0 = old behaviour) for an Acknowledge/ActiveAcknowledged transition; on timeout it refuses (BadTimeout + diagnostic). - New optional IAlarmAcknowledgeConfirmation: DriverInstanceActor awaits it after AcknowledgeAsync, off its mailbox and outside the resilience pipeline; a failure is the existing #760 AlarmAckFailed revert. - AdminUI Galaxy form carries the new knob; docs updated. Claude-Session: https://claude.ai/code/session_01GT67AD99zQQqpLCVm3p7xk
34 lines
2.2 KiB
C#
34 lines
2.2 KiB
C#
namespace ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
|
|
|
/// <summary>
|
|
/// Optional companion to <see cref="IAlarmSource"/> for a driver whose upstream can ACCEPT an acknowledge
|
|
/// without CONFIRMING it was applied (lmxopcua#869). mxaccessgw answers its <c>AcknowledgeAlarm</c> RPC OK
|
|
/// both when the <c>AckMsg</c> write was applied and when it was only sent with no completion observed; the
|
|
/// truth arrives later, as the alarm's own acknowledged transition on the alarm stream.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para>
|
|
/// The runtime calls <see cref="ConfirmAcknowledgedAsync"/> after <see cref="IAlarmSource.AcknowledgeAsync"/>
|
|
/// returned normally, with the SAME request instances, OUTSIDE the resilience pipeline (it is a wait on an
|
|
/// upstream event, not I/O, so it must neither be cut by the capability timeout nor count toward the
|
|
/// breaker) and OFF the driver actor's mailbox (the wait is seconds long).
|
|
/// </para>
|
|
/// <para>
|
|
/// It completes normally when every request is confirmed, or never needed confirming (the upstream
|
|
/// reported it applied). It throws — normally a <see cref="DriverOperationRefusedException"/> naming why —
|
|
/// when an acknowledge is not confirmed within the driver's own bounded window; the runtime then reverts
|
|
/// the condition to unacknowledged exactly as it does for an <see cref="IAlarmSource.AcknowledgeAsync"/>
|
|
/// failure (lmxopcua#760). The window is the driver's to own and bound.
|
|
/// </para>
|
|
/// </remarks>
|
|
public interface IAlarmAcknowledgeConfirmation
|
|
{
|
|
/// <summary>Waits for the upstream to confirm the acknowledges <see cref="IAlarmSource.AcknowledgeAsync"/> sent.</summary>
|
|
/// <param name="acknowledgements">The request instances previously passed to <see cref="IAlarmSource.AcknowledgeAsync"/>.</param>
|
|
/// <param name="cancellationToken">Abandons the wait (the caller then treats the acknowledge as unconfirmed).</param>
|
|
/// <returns>A task that completes when every acknowledge is confirmed or needed no confirmation.</returns>
|
|
Task ConfirmAcknowledgedAsync(
|
|
IReadOnlyList<AlarmAcknowledgeRequest> acknowledgements,
|
|
CancellationToken cancellationToken);
|
|
}
|