test(otopcua): tighten multi-device collapse assertion + clear warn-state on removal (follow-up E)
This commit is contained in:
@@ -770,6 +770,12 @@ public sealed class DriverHostActor : ReceiveActor, IWithTimers
|
||||
// Map each matched device's subset under its equipment. ONE device per partition ⇒ the mapper collapses
|
||||
// that partition's single host folder ⇒ clean EQ-n/FOCAS/...; a plan with zero new variables (all
|
||||
// shadowed by authored refs) contributes no entry.
|
||||
// NOTE: DiscoveredNodeMapper.Map's collapse predicate compares the host segment with RAW
|
||||
// StringComparer.Ordinal, whereas we grouped on the NORMALIZED host. Harmless: a real FOCAS device
|
||||
// emits one consistent HostAddress string per device, so a partition is single-host either way (collapse
|
||||
// fires). Even if two raw spellings of the same host slipped into one partition, the only effect would be
|
||||
// a retained (non-collapsed) host folder — never a mis-graft or NodeId collision (the equipment scope
|
||||
// already isolates them).
|
||||
var plans = new Dictionary<string, DiscoveredInjectionPlan>(StringComparer.Ordinal);
|
||||
foreach (var (host, nodes) in matchedNodes)
|
||||
{
|
||||
@@ -1534,6 +1540,9 @@ public sealed class DriverHostActor : ReceiveActor, IWithTimers
|
||||
if (plansByEquipment.Count == 0)
|
||||
{
|
||||
_discoveredByDriver.Remove(driverId);
|
||||
// Drop the driver's partition warn-signature too so a permanently-removed/rebound driver doesn't
|
||||
// leak a stale entry (log-level-only state; bounded by driver count — just tidiness).
|
||||
_lastPartitionWarnSignature.Remove(driverId);
|
||||
// FALLBACK (one-send invariant): this driver was SKIPPED in the bulk loop (it was cached), and its
|
||||
// plan is now FULLY DROPPED — so ApplyDiscoveredPlansForDriver won't run for it and it would
|
||||
// otherwise receive ZERO sends this pass, losing its AUTHORED subscriptions. Send the authored-only
|
||||
|
||||
Reference in New Issue
Block a user