Fix 5 code review findings (P1-P3)
P1: Wire OPC UA monitored items to MXAccess subscriptions
- Override OnCreateMonitoredItemsComplete/OnDeleteMonitoredItemsComplete
in LmxNodeManager to trigger ref-counted SubscribeTag/UnsubscribeTag
- Clients subscribing to tags now start live MXAccess data pushes
P1: Write timeout now returns false instead of true
- Previously a missing OnWriteComplete callback was treated as success
- Now correctly reports failure so OPC UA clients see the error
P1: Auto-reconnect retries from Error state (not just Disconnected)
- Monitor loop now checks both Disconnected and Error states
- Prevents permanent outages after a single failed reconnect attempt
P2: Topological sort on hierarchy before building address space
- Parents guaranteed to appear before children regardless of input order
- Prevents misplaced nodes when SQL returns unsorted results
P3: Skip redundant first-poll rebuild on startup
- ChangeDetectionService accepts initial deploy time from OpcUaService
- First poll only triggers rebuild if deploy time is actually unknown
- Eliminates duplicate DB fetch and address space rebuild at startup
All 212 tests pass (205 unit + 7 integration).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,10 +22,11 @@ namespace ZB.MOM.WW.LmxOpcUa.Host.GalaxyRepository
|
||||
public event Action? OnGalaxyChanged;
|
||||
public DateTime? LastKnownDeployTime => _lastKnownDeployTime;
|
||||
|
||||
public ChangeDetectionService(IGalaxyRepository repository, int intervalSeconds)
|
||||
public ChangeDetectionService(IGalaxyRepository repository, int intervalSeconds, DateTime? initialDeployTime = null)
|
||||
{
|
||||
_repository = repository;
|
||||
_intervalSeconds = intervalSeconds;
|
||||
_lastKnownDeployTime = initialDeployTime;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
@@ -43,8 +44,8 @@ namespace ZB.MOM.WW.LmxOpcUa.Host.GalaxyRepository
|
||||
|
||||
private async Task PollLoopAsync(CancellationToken ct)
|
||||
{
|
||||
// First poll always triggers
|
||||
bool firstPoll = true;
|
||||
// If no initial deploy time was provided, first poll triggers unconditionally
|
||||
bool firstPoll = _lastKnownDeployTime == null;
|
||||
|
||||
while (!ct.IsCancellationRequested)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user