docs(plans): close residual #2 (R1 merged, LocalDb 0.3.0); register rows 41-42 (LocalDb test flake, push.sh publish-bug family check)
This commit is contained in:
@@ -34,6 +34,8 @@ All 7 fix-now items landed via PLAN-04/05/06/07/08 (verified in review 08 round
|
||||
| 38 | **OtOpcUa: `RoslynVirtualTagEvaluatorTests` racing-clear test is load-fragile** (OtOpcUa repo, not this one) | Found by R4 during the full-suite bump verification | `Evaluate_racing_ClearCompiledScripts_never_fails_with_disposed` fails under full-solution parallel test load, passes 3/3 isolated: its design assumes at most one `ClearCompiledScripts` lands inside one evaluation (so the product's one-shot retry suffices); under contention two can. Same timing-assumption family as the R5 sweep, but lives in OtOpcUa. Test-side fix: bound clear cadence relative to observed evaluation latency, or assert on retry-exhaustion instead of zero failures. | Next OtOpcUa test session, or when it fails a run that matters |
|
||||
| 39 | **OtOpcUa: late-enabled replication cannot baseline pre-existing rows** (OtOpcUa repo, not this one) | Found by R4; documented in OtOpcUa's CLAUDE.md | `LocalDbSetup.OnReady` registers all four tables unconditionally on every driver node, so it can never pass `baselineExistingRows: true` (only correct when gated on replication being configured). Turning replication ON for a long-running default-OFF node converges on subsequent writes only — existing rows are never baselined. ScadaBridge closed this class with conditional registration + boot-time `DeregisterReplicated` self-heal (WP1.3/WP3.3); porting it is a behavior change beyond a pin bump (registered-set pinned by tests, deregistration must be pair-symmetric). Low current impact: site-a was enabled from fresh. | Before enabling replication on an established OtOpcUa node |
|
||||
| 40 | **Wall-clock sleeps used as synchronization in tests (absence-assertion class)** | Found by the R5 sweep (`9fb52153`) — a different class from the one swept, deliberately left unfixed | Tests that sleep, then assert an *absence*: `ScriptDeadlineAtEnqueueTests.cs:105,128` (two `Thread.Sleep(2s)`, with `Assert.Equal(0, scheduler.DetachedThreadCount)` depending on the sleep out-racing the watchdog — worst offender), `DeploymentWarmThenGateTests.cs:117`, `SiteAlarmLiveCacheServiceTests.cs:195,216`, `DataConnectionActorTests.cs:435` (`Task.Delay(200)` to "settle" after an `AwaitCondition`). These fail toward false-pass rather than flake, so they don't trip CI — but each is a timing pin that weakens what the test proves. Fix pattern: replace the sleep with an explicit observable edge (or assert on the positive event with a bounded wait plus a negative control). | Next test-infra session, or the first time one of these areas regresses without its test catching it |
|
||||
| 41 | **LocalDb (scadaproj) sync-session tests flake under parallel load** (scadaproj repo, not this one) | Found by R1; confirmed pre-existing at base `f627cee` (1 failure in 3 full runs) | `SyncSessionTests.Handshake_DigestMismatch_FailsClosed` and `BatchBudgetTests.Pump_RowLargerThanTheBudget_IsSentAloneRatherThanStallingTheStream` intermittently time out. Root cause looks structural, not a timing pin: on a handshake fault, `RunAsync`'s catch cancels the writer loop, which can kill the session's OWN Handshake before it transmits — the healthy peer then waits out its full 15 s cap for a message that never comes. Product-adjacent (the same early-cancel could delay a real peer's fail-closed verdict), so worth a look beyond the tests. | Next LocalDb session |
|
||||
| 42 | **`build/push.sh`-class publish bug across the family repos** | Found by R1 the hard way (incident: 25 unrelated packages briefly published to the feed, deleted + verified same session; script fixed in scadaproj `0038d46`) | The bug shape: `dotnet pack -c Release -o ./artifacts` with no project argument and no `cd`, so the script packs the CALLER'S CWD. Fixed in LocalDb's script (cd to own repo root, name the solution, absolute output path). Peer repos' publish scripts (MxAccessGateway, HistorianGateway, OtOpcUa, others in scadaproj) should be checked for the same shape — the recovery only worked because the token happened to carry delete rights. | Before anyone runs a family publish script from outside its repo, or next umbrella-repo session |
|
||||
|
||||
## Resolved (verified against the code 2026-07-10)
|
||||
Rows removed from the Deferred table above once confirmed shipped. Kept here for traceability.
|
||||
|
||||
@@ -101,10 +101,18 @@ Deliberately not fixed in this program — each has a stated reason, not an over
|
||||
set the residual called for, and `_subscriptionIds.Count`), so no accumulated counter exists to
|
||||
drift; this also closes the connection-level-failure case that let resolved climb above total.
|
||||
Regression tests: `TagResolutionCounts_*` in `DataConnectionActorBatchTests`.
|
||||
2. **Per-table `needs_snapshot` in LocalDb.** Baselining one table currently re-streams every
|
||||
registered table in both directions. Narrowing it needs an on-disk schema change LocalDb 0.2.1
|
||||
deliberately avoided (wire/schema compatibility). Documented as a follow-up in the library's
|
||||
own README and `RegisterReplicated` remarks.
|
||||
2. ~~**Per-table `needs_snapshot` in LocalDb.**~~ **RESOLVED 2026-08-15 (LocalDb 0.3.0, scadaproj
|
||||
`cea3930`; ScadaBridge pin bump `a5ac309a`, R1).** Bookkeeping schema v3 adds
|
||||
`__localdb_snapshot_state` (per-table flags); the database-wide flag survives by design for
|
||||
whole-oplog events (cap prune, impossible ack). Wire-compatible by capability negotiation, not
|
||||
a version bump: `Handshake.supports_partial_snapshot` + `SnapshotBegin.tables` (empty = all) +
|
||||
`SnapshotAck` on the unbounded control lane — a peer that doesn't advertise gets a FULL
|
||||
snapshot, which is *required* (an old receiver advances its watermark to the snapshot's as-of
|
||||
and would silently discard un-included tables' deltas). A partial snapshot moves no watermark
|
||||
on either side; debt clears on receiver ack (crash-safe), clear-on-enqueue kept for old peers.
|
||||
Library suite 199/199 incl. old-peer interop; ScadaBridge Host 490/490 on the bump. Adding an
|
||||
eleventh table to `ReplicatedTables` on a replicating site now snapshots ONE table instead of
|
||||
re-streaming all, both directions.
|
||||
3. **Event batching per proto message.** Individual `AttributeValueChanged`/`AlarmStateChanged`
|
||||
events still ride one gRPC message each; batching them is a new wire shape (proto + both
|
||||
client/server), deferred rather than folded into this program's additive-only changes.
|
||||
|
||||
Reference in New Issue
Block a user