diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian/SqliteStoreAndForwardSink.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian/SqliteStoreAndForwardSink.cs index f887990f..570ded36 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian/SqliteStoreAndForwardSink.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian/SqliteStoreAndForwardSink.cs @@ -71,7 +71,7 @@ public sealed class SqliteStoreAndForwardSink : IAlarmHistorianSink, IDisposable private readonly SemaphoreSlim _drainGate = new(1, 1); private Timer? _drainTimer; private TimeSpan _tickInterval; - private int _backoffIndex; + private volatile int _backoffIndex; private bool _disposed; // Core.AlarmHistorian-005: status fields written by the drain timer thread and @@ -655,10 +655,11 @@ public sealed class SqliteStoreAndForwardSink : IAlarmHistorianSink, IDisposable await cmd.ExecuteNonQueryAsync(ct).ConfigureAwait(false); } Interlocked.Add(ref _queuedRowCount, -toEvict); - lock (_statusLock) { _evictedCount += toEvict; } + long lifetimeEvicted; + lock (_statusLock) { _evictedCount += toEvict; lifetimeEvicted = _evictedCount; } _logger.Warning( "Historian queue at capacity {Cap} — evicted {Count} oldest row(s) to make room (lifetime evictions: {Total})", - _capacity, toEvict, _evictedCount); + _capacity, toEvict, lifetimeEvicted); } private void PurgeAgedDeadLetters(SqliteConnection conn)