docs(plans): follow-up batch #674-#678 design
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# Follow-up batch #674–#678 — design (2026-10-11)
|
||||
|
||||
Follow-ups filed after the #667–#673 batch. Base: master `bc03adb1`. User-approved; recommended choices throughout.
|
||||
Investigation found three new defects (client endpoint port not rewritten; role overlays never load on
|
||||
cluster-role nodes; Gateway Count/Average mode mapping) — the first two are fixed here, the third is filed.
|
||||
|
||||
| Lane | Scope | Model |
|
||||
|---|---|---|
|
||||
| L1 | #674 HistoryUpdate posture | opus |
|
||||
| L2 | #675 reverse event paging | opus |
|
||||
| L3 | #677 aggregates | opus |
|
||||
| L4 | client (#677.5, #678.5/.6, #674.6) | sonnet |
|
||||
| L5 | #676 OpcUaClient | opus |
|
||||
| L6 | #678.1–.4 + role-overlay bug | sonnet |
|
||||
|
||||
## L1 — #674
|
||||
- **674.1:** spike on QuestDB 10.0.1 showed TTL is judged against `min(maxTs, wall clock)` (`cairo.ttl.use.wall.clock=true`
|
||||
default) — a 2066 row evicted nothing. Add a QuestDB integration test pinning that + a docs note. HistoryUpdate refuses a
|
||||
SourceTimestamp beyond `now + ServerHistorian:HistoryUpdateMaxFutureSkew` (default 1 day) with `BadOutOfRange`; the
|
||||
recorder is not bounded.
|
||||
- **674.2:** SqlServer base schema requirement back to v1; `SupportsModifiedTrail` (v ≥ 2). On v1: modified reads and
|
||||
HistoryUpdate ⇒ `BadHistoryOperationUnsupported` (nothing sent), retention skips `SampleModified`, one Warning per boot.
|
||||
- **674.3:** HistoryUpdate Primary-gated (off-Primary ⇒ `BadInvalidState`, same shape as `NativeAlarmAckPrimaryGate`).
|
||||
Retry duplicates on QuestDB documented; no DEDUP key.
|
||||
- 674.4/674.5 documented only.
|
||||
|
||||
## L2 — #675
|
||||
- Reverse event reads: `reverse` flag on `IHistorianDataSource.ReadEventsAsync`; SqlServer/QuestDB order DESC and take
|
||||
the top N; direction-aware cursor (reuse raw `SliceTieCluster(reverse:)`); Gateway ⇒ `BadHistoryOperationUnsupported`
|
||||
for reverse.
|
||||
- End-only event read ⇒ backward (mirrors raw).
|
||||
- Offline test pinning `DateTime.MaxValue` through the Gateway proto/FILETIME encoding; live AVEVA leg stays open (VPN).
|
||||
|
||||
## L3 — #677
|
||||
- Reverse processed reads per SDK/Part 13: buckets anchored at the later (start) time stepping back, partial bucket
|
||||
earliest, bucket timestamp = later edge. Parity test vs SDK `AggregateCalculator`. Client-visible, release-noted.
|
||||
- Partial bit also when the data starts inside a bucket (no bounding prior).
|
||||
- `AggregateConfiguration`: `UseServerCapabilitiesDefaults` or values equal to the server defaults ⇒ served; otherwise
|
||||
per-node `BadAggregateConfigurationRejected`.
|
||||
- Gateway provisioner sends `IntegralDivisor = 1` (proto3 default 0). Live magnitude check stays open (VPN).
|
||||
|
||||
## L4 — client
|
||||
- `EndpointSelector.SelectBest` rewrites host **and** port of the advertised endpoint (fixes rig `:4841` cert error).
|
||||
- Client aggregate enum/mapper/CLI/UI gain TimeAverage, TimeAverage2, Total, Total2, Interpolative.
|
||||
- History read refusal ⇒ one-line `CommandException`, no stack trace.
|
||||
- `NodeManagerHistoryReadTests` non-historized case sets `IsReadModified=false`.
|
||||
|
||||
## L5 — #676
|
||||
- Driver endpoint host+port rewrite; in-process TCP-stall proxy wire test (in-place blip, same session, Good republish,
|
||||
no regression).
|
||||
- Remove dead `ReconnectPeriod` (options, AdminUI form, docs, tests); stored JSON with it still parses.
|
||||
- New opt-in `IDriverConnectionLossSource` (Core.Abstractions): raised once per session by OpcUaClient only on a
|
||||
definitive loss (`BadSessionIdInvalid`/`BadSessionClosed`/`BadSessionNotActivated`/subscription lost);
|
||||
`DriverInstanceActor` (attach PreStart, detach PostStop) turns it into `DisconnectObserved` only while Connected.
|
||||
Ambiguous codes keep going through the #527 watchdog.
|
||||
- Information-level per-recovery replay-drop summary. Equal-timestamp drop documented.
|
||||
|
||||
## L6 — small
|
||||
- Retention: mid-command cancel test + `ClearPool` fallback test with falsification control.
|
||||
- #672 tests: initial-state unreachable path; strengthen `Self_unreachable_is_ignored`; edge-triggered Debug log.
|
||||
- FOCAS `WireBackendTests`: wait for motor speeds too; `WaitFor` fails on timeout.
|
||||
- QuestDB TTL-cleared log wording; `docker-dev/docker-compose.debug.yml` Debug recipe.
|
||||
- Role overlay suffix built from plain roles only — after auditing each `appsettings.<role>.json` and stripping anything
|
||||
that would change production behaviour on activation.
|
||||
|
||||
## Live gates (docker-dev)
|
||||
1. opc-plc `docker restart` recovers in seconds (was ~100 s); pause-blip re-check.
|
||||
2. Client.CLI connects to `:4841`–`:4845`.
|
||||
3. HistoryUpdate refused on the Secondary, accepted on the Primary; v1-schema DB keeps historizing.
|
||||
4. Reverse event paging and reverse processed reads over the wire, SqlServer + QuestDB.
|
||||
Reference in New Issue
Block a user