fix(dcl): deliver initial-read seed value after subscription registration #2

Merged
dohertj2 merged 1 commits from fix/dcl-seed-after-registration into main 2026-06-16 18:47:38 -04:00
Owner

Problem

ScadaBridge Site instances bound to MxGateway tags whose value never changes (e.g. idle MES MESReceiver_* fields) stayed at quality Uncertain forever — observed live on wonder-app-vd03 for reactors Z28061/Z28062 (48 bindings, all Uncertain) despite the gateway returning Good values.

Root cause

DataConnectionActor.HandleSubscribe seeded each tag's initial value by Tell-ing TagValueReceived from its background subscribe task, which completes before HandleSubscribeCompleted registers the instance's tags in _subscriptionsByInstance. The seed therefore reached HandleTagValueReceived while the fan-out map was still empty and was silently dropped. A tag that soon gets an OnDataChange recovers; a static tag (no further change) never does.

Fix

Seed values now ride back on the SubscribeCompleted message and are delivered after registration, re-entering HandleTagValueReceived via Self (reusing the generation guard, fan-out and quality accounting). Only resolved tags are seeded, so an unresolved tag's Bad-quality signal is not masked.

Tests

  • New regression test DCL026_StaticTagSeedValue_IsDeliveredAfterRegistration.
  • Full DataConnectionLayer.Tests green (155).

Verification

Deployed to wonder-app-vd03; Z28061 & Z28062 now read 24/24 Good with live values (e.g. LeftMESReceiver.MoveInBatchID=107241, MoveInCompleteFlag=True).

## Problem ScadaBridge Site instances bound to MxGateway tags whose value never changes (e.g. idle MES `MESReceiver_*` fields) stayed at quality **Uncertain** forever — observed live on wonder-app-vd03 for reactors Z28061/Z28062 (48 bindings, all Uncertain) despite the gateway returning Good values. ## Root cause `DataConnectionActor.HandleSubscribe` seeded each tag's initial value by `Tell`-ing `TagValueReceived` from its background subscribe **task**, which completes *before* `HandleSubscribeCompleted` registers the instance's tags in `_subscriptionsByInstance`. The seed therefore reached `HandleTagValueReceived` while the fan-out map was still empty and was silently dropped. A tag that soon gets an OnDataChange recovers; a **static** tag (no further change) never does. ## Fix Seed values now ride back on the `SubscribeCompleted` message and are delivered **after** registration, re-entering `HandleTagValueReceived` via `Self` (reusing the generation guard, fan-out and quality accounting). Only resolved tags are seeded, so an unresolved tag's Bad-quality signal is not masked. ## Tests - New regression test `DCL026_StaticTagSeedValue_IsDeliveredAfterRegistration`. - Full `DataConnectionLayer.Tests` green (155). ## Verification Deployed to wonder-app-vd03; Z28061 & Z28062 now read **24/24 Good** with live values (e.g. `LeftMESReceiver.MoveInBatchID=107241`, `MoveInCompleteFlag=True`).
dohertj2 added 1 commit 2026-06-16 18:43:28 -04:00
DataConnectionActor seeded a tag's initial value by Tell-ing TagValueReceived
from HandleSubscribe's background task, which runs BEFORE HandleSubscribeCompleted
registers the instance's tags in _subscriptionsByInstance. HandleTagValueReceived's
fan-out then found no subscriber and dropped the value. A tag that soon gets a
data-change notification recovers, but a STATIC tag (e.g. an idle MES field that
never changes) was left Uncertain forever — the dropped seed was its only value.

Seeds now ride back on SubscribeCompleted and are delivered after registration,
reusing HandleTagValueReceived's generation guard, fan-out and quality accounting.
+1 regression test (DCL026).
dohertj2 merged commit 06ef1779bd into main 2026-06-16 18:47:38 -04:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/ScadaBridge#2