fix(driver-abcip): resolve Low code-review findings (Driver.AbCip-007,011,012,013,015)
- Driver.AbCip-007: inject an optional ILogger<AbCipDriver> / ILogger<AbCipAlarmProjection> (default NullLogger) and log around every read / write / template-fetch / probe / alarm-poll failure path. - Driver.AbCip-011: LogWarning when InitializeAsync is configured with Probe.Enabled=true but ProbeTagPath is blank — operators now see why GetHostStatuses keeps reporting Unknown. - Driver.AbCip-012: documented the LibplctagTemplateReader per-call Tag cost as accepted given libplctag's own connection pool and the low-frequency discovery use-case. - Driver.AbCip-013: per-device AllowPacking + ConnectionSize overrides on AbCipDeviceOptions, threaded through AbCipTagCreateParams; central BuildCreateParams helper replaces five ad-hoc clones; AllowPacking now reaches Tag.AllowPacking at runtime. - Driver.AbCip-015: stale-comment sweep — every PR-N forward-reference is rewritten to describe present behaviour. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip;
|
||||
@@ -32,14 +34,16 @@ internal sealed class AbCipAlarmProjection : IAsyncDisposable
|
||||
{
|
||||
private readonly AbCipDriver _driver;
|
||||
private readonly TimeSpan _pollInterval;
|
||||
private readonly ILogger _logger;
|
||||
private readonly Dictionary<long, Subscription> _subs = new();
|
||||
private readonly Lock _subsLock = new();
|
||||
private long _nextId;
|
||||
|
||||
public AbCipAlarmProjection(AbCipDriver driver, TimeSpan pollInterval)
|
||||
public AbCipAlarmProjection(AbCipDriver driver, TimeSpan pollInterval, ILogger? logger = null)
|
||||
{
|
||||
_driver = driver;
|
||||
_pollInterval = pollInterval;
|
||||
_logger = logger ?? NullLogger.Instance;
|
||||
}
|
||||
|
||||
public async Task<IAlarmSubscriptionHandle> SubscribeAsync(
|
||||
@@ -158,7 +162,14 @@ internal sealed class AbCipAlarmProjection : IAsyncDisposable
|
||||
Tick(sub, results);
|
||||
}
|
||||
catch (OperationCanceledException) when (ct.IsCancellationRequested) { break; }
|
||||
catch { /* per-tick failures are non-fatal; next tick retries */ }
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Per-tick failures are non-fatal; next tick retries. Log at debug because a
|
||||
// wedged controller produces one exception per tick and the operator already
|
||||
// sees the failed-read warning from ReadAsync below this layer; this log just
|
||||
// confirms the alarm projection loop is still running.
|
||||
_logger.LogDebug(ex, "AbCip alarm-projection poll tick failed (will retry)");
|
||||
}
|
||||
|
||||
try { await Task.Delay(_pollInterval, ct).ConfigureAwait(false); }
|
||||
catch (OperationCanceledException) { break; }
|
||||
|
||||
Reference in New Issue
Block a user