fix(lmxproxy): resolve write timeout — bypass OnWriteComplete callback for supervisory writes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-03-22 04:39:14 -04:00
parent e2c204b62b
commit c5d4849bd3
6 changed files with 36 additions and 119 deletions

View File

@@ -69,6 +69,8 @@ namespace ZB.MOM.WW.LmxProxy.Host.MxAccess
/// <summary>
/// COM event handler for MxAccess OnWriteComplete events.
/// Signature matches the ArchestrA.MxAccess ILMXProxyServerEvents interface.
/// Kept wired for diagnostic logging only — writes are resolved synchronously
/// when the Write() COM call returns without throwing.
/// </summary>
private void OnWriteComplete(
int hLMXServerHandle,
@@ -77,57 +79,23 @@ namespace ZB.MOM.WW.LmxProxy.Host.MxAccess
{
try
{
TaskCompletionSource<bool> tcs;
lock (_lock)
{
if (!_pendingWrites.TryGetValue(phItemHandle, out tcs))
{
Log.Debug("WriteComplete for unknown handle {Handle}", phItemHandle);
return;
}
_pendingWrites.Remove(phItemHandle);
}
if (ItemStatus != null && ItemStatus.Length > 0)
{
var status = ItemStatus[0];
if (status.success == 0)
{
string errorMsg = GetWriteErrorMessage(status.detail);
Log.Warning("Write failed for handle {Handle}: {Error} (Category={Category}, Detail={Detail})",
Log.Warning("OnWriteComplete callback: write failed for handle {Handle}: {Error} (Category={Category}, Detail={Detail})",
phItemHandle, errorMsg, status.category, status.detail);
tcs.TrySetException(new InvalidOperationException(
string.Format("Write failed: {0}", errorMsg)));
}
else
{
Log.Debug("Write completed successfully for handle {Handle}", phItemHandle);
tcs.TrySetResult(true);
Log.Debug("OnWriteComplete callback: write succeeded for handle {Handle}", phItemHandle);
}
}
else
{
// No status means success
Log.Debug("Write completed for handle {Handle} with no status", phItemHandle);
tcs.TrySetResult(true);
}
// Clean up the item after write completes
lock (_lock)
{
if (_lmxProxy != null && phItemHandle > 0)
{
try
{
_lmxProxy.UnAdvise(_connectionHandle, phItemHandle);
_lmxProxy.RemoveItem(_connectionHandle, phItemHandle);
}
catch (Exception ex)
{
Log.Debug(ex, "Error cleaning up after write for handle {Handle}", phItemHandle);
}
}
Log.Debug("OnWriteComplete callback: no status for handle {Handle}", phItemHandle);
}
}
catch (Exception ex)