docs(code): honest rationales — Akka restart semantics, per-key shards, EF literal inlining; retire or annotate orphaned members
This commit is contained in:
@@ -281,10 +281,17 @@ non-`Healthy` state **and** its `LastSuccessfulRead` has been frozen for 90 s. T
|
||||
all 12: nine poll drivers via `Degraded`, MQTT via live connection state, Galaxy via its reconnect
|
||||
supervisor. `CalculationDriver` reports `Healthy` while running and so can never trip — correct, as it has
|
||||
no transport. Re-check this if a new driver lands.
|
||||
- ⚠️ **The reconnect retry MUST tear down before re-initialising.** `ModbusDriver` (`_transport`) and
|
||||
`MqttDriver` (`_connection`) overwrite an `IAsyncDisposable` field inside `InitializeAsync` without
|
||||
disposing the old one, so re-initialising without `ShutdownAsync` leaks a socket per attempt — ~360 for an
|
||||
hour-long outage at the 10 s retry interval. Latent while only a manual Force Reconnect reached this path.
|
||||
- **The reconnect retry MUST tear down before re-initialising — FIXED in both drivers, keep it that way.**
|
||||
`ModbusDriver` (`_transport`) and `MqttDriver` (`_connection`) used to overwrite an `IAsyncDisposable`
|
||||
field inside `InitializeAsync` without disposing the old one, so re-initialising without `ShutdownAsync`
|
||||
leaked a socket per attempt — ~360 for an hour-long outage at the 10 s retry interval. Both now dispose
|
||||
first: `ModbusDriver.InitializeCoreAsync` releases `_transport` **and** the `_probeCts`/`_reprobeCts`
|
||||
probe loops before rebuilding them (`c3970a2e` + the lifecycle gate in `409a58b6`), deliberately *not*
|
||||
via the shared `TeardownAsync()` because that would also drop `_poll` and every active subscription with
|
||||
nothing to re-drive them; `MqttDriver.InitializeCoreAsync` calls its (idempotent) `TeardownAsync()` first,
|
||||
which reaches `_connection` and the primary-host connection (`2b4b3fcb`). The path is no longer latent —
|
||||
the comms-loss watchdog reaches it, not just a manual Force Reconnect — so a new driver, or a new
|
||||
`IAsyncDisposable` field on these two, must repeat the dispose-before-overwrite.
|
||||
- The threshold is hardcoded (`DefaultCommsLossTimeout`), matching `HealthPollInterval` /
|
||||
`DefaultReconnectInterval`. Unlike the #523 drift detector this generates **no** traffic on a healthy
|
||||
system — it is a local `GetHealth()` read, and only reaches the network once a driver has already stopped
|
||||
|
||||
Reference in New Issue
Block a user