feat(worker): correlate OnWriteComplete onto plain Write/Write2 replies (06/S-1 follow-up)
OtOpcUa's dominant FreeAccess write path goes out as MX_COMMAND_KIND_WRITE, not WriteSecured — the original 06/S-1 brief mis-scoped the correlation, so a refused plain write was invisible on the unary reply (verified live on windev 2026-08-09). ExecuteWrite/ExecuteWrite2 now use the same pre-call version baseline + bounded pump-wait as the secured kinds. Bulk writes stay fire-and-forget.
This commit is contained in:
@@ -427,13 +427,28 @@ public sealed class MxAccessCommandExecutor : IStaCommandExecutor
|
||||
return CreateInvalidRequestReply(command, "Write command value is required.");
|
||||
}
|
||||
|
||||
// Same pre-call baseline rule as ExecuteWriteSecured: plain Write is
|
||||
// also fire-and-forget in MXAccess, and its commit outcome only exists
|
||||
// in the later OnWriteComplete callback.
|
||||
MxAccessWriteCompletionCache completionCache = session.WriteCompletionCache;
|
||||
ulong completionBaseline = completionCache.CurrentVersion(
|
||||
writeCommand.ServerHandle,
|
||||
writeCommand.ItemHandle);
|
||||
|
||||
session.Write(
|
||||
writeCommand.ServerHandle,
|
||||
writeCommand.ItemHandle,
|
||||
variantConverter.ConvertToComValue(writeCommand.Value),
|
||||
writeCommand.UserId);
|
||||
|
||||
return CreateOkReply(command);
|
||||
MxCommandReply reply = CreateOkReply(command);
|
||||
AwaitWriteCompletion(
|
||||
reply,
|
||||
completionCache,
|
||||
writeCommand.ServerHandle,
|
||||
writeCommand.ItemHandle,
|
||||
completionBaseline);
|
||||
return reply;
|
||||
}
|
||||
|
||||
private MxCommandReply ExecuteWrite2(StaCommand command)
|
||||
@@ -454,6 +469,12 @@ public sealed class MxAccessCommandExecutor : IStaCommandExecutor
|
||||
return CreateInvalidRequestReply(command, "Write2 command timestamp value is required.");
|
||||
}
|
||||
|
||||
// Same pre-call baseline rule as ExecuteWriteSecured.
|
||||
MxAccessWriteCompletionCache completionCache = session.WriteCompletionCache;
|
||||
ulong completionBaseline = completionCache.CurrentVersion(
|
||||
write2Command.ServerHandle,
|
||||
write2Command.ItemHandle);
|
||||
|
||||
session.Write2(
|
||||
write2Command.ServerHandle,
|
||||
write2Command.ItemHandle,
|
||||
@@ -461,7 +482,14 @@ public sealed class MxAccessCommandExecutor : IStaCommandExecutor
|
||||
variantConverter.ConvertToComValue(write2Command.TimestampValue),
|
||||
write2Command.UserId);
|
||||
|
||||
return CreateOkReply(command);
|
||||
MxCommandReply reply = CreateOkReply(command);
|
||||
AwaitWriteCompletion(
|
||||
reply,
|
||||
completionCache,
|
||||
write2Command.ServerHandle,
|
||||
write2Command.ItemHandle,
|
||||
completionBaseline);
|
||||
return reply;
|
||||
}
|
||||
|
||||
private MxCommandReply ExecuteWriteSecured(StaCommand command)
|
||||
|
||||
Reference in New Issue
Block a user