fix(opcua): RunContinuationsAsynchronously so revert never re-enters the write Lock
This commit is contained in:
@@ -638,7 +638,10 @@ public sealed class OtOpcUaNodeManager : CustomNodeManager2
|
|||||||
|
|
||||||
// Fire-and-forget — MUST NOT block under Lock. On a FAILED outcome, compare-and-revert (off-Lock
|
// Fire-and-forget — MUST NOT block under Lock. On a FAILED outcome, compare-and-revert (off-Lock
|
||||||
// continuation). A faulted/cancelled WriteAsync is treated as a failure so the optimistic value never
|
// continuation). A faulted/cancelled WriteAsync is treated as a failure so the optimistic value never
|
||||||
// sticks when the route never resolved a real outcome.
|
// sticks when the route never resolved a real outcome. RunContinuationsAsynchronously guarantees the
|
||||||
|
// revert never runs inline on the SDK write thread (the gateway can return a synchronously-completed
|
||||||
|
// task — e.g. its boot-window "no DriverHostActor yet" branch), so RevertOptimisticWriteIfNeeded never
|
||||||
|
// re-enters lock (Lock) while CustomNodeManager2.Write still holds it.
|
||||||
_ = gateway.WriteAsync(nodeKey, optimisticValue, CancellationToken.None)
|
_ = gateway.WriteAsync(nodeKey, optimisticValue, CancellationToken.None)
|
||||||
.ContinueWith(
|
.ContinueWith(
|
||||||
t =>
|
t =>
|
||||||
@@ -646,7 +649,7 @@ public sealed class OtOpcUaNodeManager : CustomNodeManager2
|
|||||||
var outcome = t.IsCompletedSuccessfully ? t.Result : new NodeWriteOutcome(false, "write dispatch faulted");
|
var outcome = t.IsCompletedSuccessfully ? t.Result : new NodeWriteOutcome(false, "write dispatch faulted");
|
||||||
RevertOptimisticWriteIfNeeded(nodeKey, outcome, optimisticValue, priorValue, priorStatus);
|
RevertOptimisticWriteIfNeeded(nodeKey, outcome, optimisticValue, priorValue, priorStatus);
|
||||||
},
|
},
|
||||||
CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Default);
|
CancellationToken.None, TaskContinuationOptions.RunContinuationsAsynchronously, TaskScheduler.Default);
|
||||||
|
|
||||||
return ServiceResult.Good;
|
return ServiceResult.Good;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user