FOCAS/AbLegacy InitializeAsync orphans previous DeviceState loops when called without teardown #630

Closed
opened 2026-10-08 09:21:56 -04:00 by dohertj2 · 1 comment
Owner

Found by review R5 (#602). FocasDriver.InitializeAsync (:207) and AbLegacyDriver.InitializeAsync (:180) overwrite _devices[host] = new DeviceState(...) without cancelling, joining or disposing the old state's probe, recycle and fixed-tree loops (each holding a client). DriverInstanceActor.AdoptConfigDuringInit (~:831) calls InitializeAsync without teardownFirst, so an ApplyDelta that arrives mid-init orphans a full loop set that neither ShutdownAsync nor the new shutdown join (#602 STAB-23/6) can reach.

This is the dispose-before-overwrite rule from the comms-loss section of CLAUDE.md, which Modbus and MQTT already follow.

  • At the top of InitializeAsync in both drivers, cancel, bounded-join and dispose any existing _devices entries
  • Test: Initialize twice, assert the first state's loops have finished and its clients are disposed (with a positive control that the loops were running)
  • Check the same pattern in the other poll drivers

Filed 2026-10-08 by the hardware-available issue sweep.

Found by review R5 (#602). `FocasDriver.InitializeAsync` (~:207) and `AbLegacyDriver.InitializeAsync` (~:180) overwrite `_devices[host] = new DeviceState(...)` without cancelling, joining or disposing the old state's probe, recycle and fixed-tree loops (each holding a client). `DriverInstanceActor.AdoptConfigDuringInit` (~:831) calls `InitializeAsync` without `teardownFirst`, so an ApplyDelta that arrives mid-init orphans a full loop set that neither `ShutdownAsync` nor the new shutdown join (#602 STAB-23/6) can reach. This is the dispose-before-overwrite rule from the comms-loss section of CLAUDE.md, which Modbus and MQTT already follow. - [ ] At the top of `InitializeAsync` in both drivers, cancel, bounded-join and dispose any existing `_devices` entries - [ ] Test: Initialize twice, assert the first state's loops have finished and its clients are disposed (with a positive control that the loops were running) - [ ] Check the same pattern in the other poll drivers *Filed 2026-10-08 by the hardware-available issue sweep.*
Author
Owner

Fixed in 2377da3c (Merge b626-630): FOCAS, AbLegacy, AbCip, TwinCAT, S7 and OpcUaClient InitializeAsync now release prior device/session state (cancel, bounded join, dispose) before re-initialising.

Fixed in 2377da3c (Merge b626-630): FOCAS, AbLegacy, AbCip, TwinCAT, S7 and OpcUaClient InitializeAsync now release prior device/session state (cancel, bounded join, dispose) before re-initialising.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/lmxopcua#630