refactor(driver-pages): address post-review follow-ups
- DriverInstanceSpec carries ClusterId from the deployment artifact; DriverHostActor threads the real cluster identity into DriverInstanceActor instead of the local NodeId. Old pre-PR artifacts without a ClusterId field fall back to the NodeId so in-flight deployments keep working. - DriverHostActor.ChildEntry holds the full DriverInstanceSpec (was only carrying DriverType + LastConfigJson). Restart respawns preserve RowId, Name, Enabled, ClusterId — no placeholder values. - Drop the unnecessary _faultLock on DriverInstanceActor — every read/write site runs inside an Akka message handler which is single-threaded per actor instance. - DriverStatusPanel.DisposeAsync awaits Timer.DisposeAsync so an in-flight 5s tick can't invoke StateHasChanged on a component whose hub has already been torn down.
This commit is contained in:
@@ -72,9 +72,12 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
private readonly ILoggingAdapter _log = Context.GetLogger();
|
||||
private string? _currentConfigJson;
|
||||
|
||||
/// <summary>Timestamps of recent Faulted-state transitions; used to compute the 5-minute error count.</summary>
|
||||
/// <summary>
|
||||
/// Timestamps of recent Faulted-state transitions; used to compute the 5-minute error count.
|
||||
/// No lock needed — every read/write site runs inside an Akka message handler, which is
|
||||
/// single-threaded per actor instance.
|
||||
/// </summary>
|
||||
private readonly Queue<DateTime> _faultTimestamps = new();
|
||||
private readonly object _faultLock = new();
|
||||
|
||||
/// <summary>Active subscription handle (null when not subscribed). Lifetime is one-per-actor —
|
||||
/// re-subscribe across reconnects is the consumer's responsibility today (subscribe-once
|
||||
@@ -412,28 +415,19 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
|
||||
private static bool IsGoodStatus(uint statusCode) => (statusCode >> 30) == 0;
|
||||
|
||||
/// <summary>
|
||||
/// Records a transition into a Faulted / error state for the 5-minute sliding counter.
|
||||
/// Thread-safe: called from actor message-handling (single-threaded) but guard is cheap.
|
||||
/// </summary>
|
||||
/// <summary>Records a transition into a Faulted / error state for the 5-minute sliding counter.</summary>
|
||||
private void RecordFault()
|
||||
{
|
||||
lock (_faultLock)
|
||||
{
|
||||
_faultTimestamps.Enqueue(DateTime.UtcNow);
|
||||
}
|
||||
_faultTimestamps.Enqueue(DateTime.UtcNow);
|
||||
}
|
||||
|
||||
/// <summary>Returns how many fault transitions occurred in the last 5 minutes.</summary>
|
||||
private int ErrorCount5Min()
|
||||
{
|
||||
var cutoff = DateTime.UtcNow.AddMinutes(-5);
|
||||
lock (_faultLock)
|
||||
{
|
||||
while (_faultTimestamps.Count > 0 && _faultTimestamps.Peek() < cutoff)
|
||||
_faultTimestamps.Dequeue();
|
||||
return _faultTimestamps.Count;
|
||||
}
|
||||
while (_faultTimestamps.Count > 0 && _faultTimestamps.Peek() < cutoff)
|
||||
_faultTimestamps.Dequeue();
|
||||
return _faultTimestamps.Count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user