Commit Graph

1948 Commits

Author SHA1 Message Date
Joseph Doherty 6b46c485ef test(historian): bounded-wait durability read; honest nondeterminism notes on the #491 controls 2026-08-17 04:07:08 -04:00
Joseph Doherty 20022083df perf(s7): span leftovers batch through multi-var read PDUs with per-chunk fallback 2026-08-17 04:05:42 -04:00
Joseph Doherty 5ae430237f fix(alarms): background tasks register before they start; volatile _disposed 2026-08-17 04:04:45 -04:00
Joseph Doherty cda82c074e perf(mtconnect): stream sample-chunk parsing through XmlReader; no per-chunk document tree 2026-08-17 03:57:16 -04:00
Joseph Doherty d884934593 fix(acl): shard eviction swaps the shard object so _globalCount cannot over-subtract; concurrency stress test 2026-08-17 03:55:13 -04:00
Joseph Doherty c149410ba3 test(adminui): SQL-Server-backed pins for the drift watermark aggregate and the rename scan's collation widening 2026-08-17 03:53:16 -04:00
Joseph Doherty 7870c91fe4 fix(historian): a shutdown cancellation mid-drain is a pass abort, not a per-tag failure 2026-08-17 03:52:55 -04:00
Joseph Doherty dba5f806d3 fix(runtime): explicit 30s command timeout on the Direct-apply artifact read 2026-08-17 03:49:27 -04:00
Joseph Doherty 6ee553cf8f feat(s7): expose ReadMultipleVarsAsync through the IS7Plc seam 2026-08-17 03:48:15 -04:00
Joseph Doherty c4d8e4a200 fix(acl): revalidation memo rejects empty node identifiers, mirroring the authorizer's guard 2026-08-17 03:47:19 -04:00
Joseph Doherty e22ecea008 feat(drivers): per-driver poll-overrun meter on the shared OtOpcUa Meter; NoteOverrun + backoffCap doc notes 2026-08-17 03:46:27 -04:00
Joseph Doherty acb3772426 fix(s7): validate span-read options at parse time; document the over-PDU degradation 2026-08-17 03:45:14 -04:00
Joseph Doherty c8a7014388 fix(alarms): replacement drainer starts on a fresh stack; honest bounds in the latch comments 2026-08-16 05:57:05 -04:00
Joseph Doherty 445bb855e2 fix: release the alarm drain latch on escape; cancel before disposing the page poll timers 2026-08-16 05:40:27 -04:00
Joseph Doherty dbc9223206 docs(code): correct comments stale after the perf remainder 2026-08-16 05:09:00 -04:00
Joseph Doherty 451273c860 test(historian): pin the failed-batch-append branch; correct its loss-accounting docs
The batched ingest's append-failure catch had zero coverage, and two doc
statements overstated the loss: the Warning said the burst's values were
"dropped", and RecorderStatus.OutboxAppendFailures said "the value was
dropped, not recorded". The outbox contract is prefix-never-orphan, so a
partial-prefix failure leaves entries durably queued that drain normally.

- New test pins the branch: one 3-item burst whose group commit commits a
  1-entry prefix then throws => OutboxAppendFailures == 1 (per burst, not
  per value), TotalRecorded == 0, actor alive, and the prefix still reaches
  the writer via the post-failure DrainTick (drainInterval 30s, so the
  steady cadence cannot account for it). Falsified twice: counting per item
  and dropping the drain nudge each turn it red.
- Second test pins the OperationCanceledException filter from its
  observable side - a cancel that is NOT shutdown is metered, not swallowed.
  Removing the 'when (_lifetime.IsCancellationRequested)' turns it red. The
  shutdown side has no cheap seam (the counter dies with the actor).
- Docs corrected: OutboxAppendFailures counts FAILED BATCH APPENDS, one per
  burst whatever its size (a granularity change from the per-value era), and
  is not a count of values lost; TotalRecorded under-counts when a commit
  fails after a partial prefix. Log message says "failed to append" and
  names the prefix. No functional change beyond the message string.

Also folds in the DrainBatchSize default alignment behind 0298a0b9: the
recorder's two ctor defaults and its non-positive fallback still said 64
while ContinuousHistorizationOptions.DrainBatchSize now defaults to 1024.
No test pinned the old 64.
2026-08-16 04:50:30 -04:00
Joseph Doherty 0298a0b944 chore(historian): batch-era defaults + appsettings/doc alignment 2026-08-16 04:48:55 -04:00
Joseph Doherty 5b92eb0ff6 perf(runtime): direct-mode artifact read piped off the host mailbox 2026-08-16 04:48:02 -04:00
Joseph Doherty ca87329a83 fix(adminui): dedup + chunk the rename script-scan OR-chain 2026-08-16 04:36:03 -04:00
Joseph Doherty 485f4ea1e8 test(polling): tolerate one scheduler blip in the fast-reader overrun control 2026-08-16 04:35:01 -04:00
Joseph Doherty 384568b47a perf(historian): batch ingest — one group commit per value burst 2026-08-16 04:33:35 -04:00
Joseph Doherty aad7583b79 test(acl): pin TranslateBrowsePath survivor order through the compaction 2026-08-16 04:29:27 -04:00
Joseph Doherty b6275f439c perf(runtime): per-driver index for connectivity fans; comms-loss is one batch 2026-08-16 04:27:20 -04:00
Joseph Doherty 9cf400f1e8 perf(drivers): fixed-rate poll pacing with overrun counter; non-blocking unsubscribe 2026-08-16 04:26:20 -04:00
Joseph Doherty 684e59d871 perf(adminui): drift chip recomposes only when the config-edit watermark moves 2026-08-16 04:25:56 -04:00
Joseph Doherty d5f573b019 fix(abcip): single-flight cold-connect per device — backoff survives the parallel read window 2026-08-16 04:24:59 -04:00
Joseph Doherty a76b4e0740 perf(historian): bounded-parallel per-tag drain (DrainConcurrency, default 8) 2026-08-16 04:21:18 -04:00
Joseph Doherty d8a17f2e34 perf(acl): authorizer hot path — cache lookup before scope build, lazy deny reasons 2026-08-16 04:19:47 -04:00
Joseph Doherty 7320586512 fix(historian): incremental batch-append bookkeeping; genuine group-commit durability pin 2026-08-16 04:18:38 -04:00
Joseph Doherty fbe8aaad9d perf(acl): dedup subscription revalidation by (session, node) 2026-08-16 04:18:03 -04:00
Joseph Doherty 50035b36bb test(mqtt): pin status-code half of republish suppression; note Sparkplug bypass 2026-08-16 04:16:35 -04:00
Joseph Doherty 39f67a0fce perf(s7): span-grouped reads — one PDU per contiguous block instead of one per tag 2026-08-16 04:15:37 -04:00
Joseph Doherty 409a58b624 fix(modbus): lifecycle gate + non-vacuous reprobe regression test 2026-08-16 04:07:27 -04:00
Joseph Doherty 140bf0c131 perf(adminui): pooled DbContext factory; role-grants reads per-call, not per-circuit 2026-08-16 04:05:34 -04:00
Joseph Doherty 34f836e03c perf(mtconnect): sample chunks parse from bytes, no per-chunk string copies 2026-08-16 04:05:15 -04:00
Joseph Doherty 3795899d10 perf(adminui): 5s snapshot cache in front of the script tag catalog 2026-08-16 04:05:07 -04:00
Joseph Doherty ba977dbe0d perf(adminui): raw tree renders tag rows from a projection without TagConfig 2026-08-16 04:04:32 -04:00
Joseph Doherty fa36d64e8f perf(adminui): one guard round-trip per bulk reference add 2026-08-16 04:03:49 -04:00
Joseph Doherty 541a223b96 perf(acl): O(n) browse/translate filtering compaction 2026-08-16 04:03:32 -04:00
Joseph Doherty d6a4fbd648 perf(abcip): bounded-parallel tag reads (MaxConcurrentReads, default 8) 2026-08-16 04:02:40 -04:00
Joseph Doherty 5df793e79a perf(alarms): dirty-set coalescing — one evaluation per alarm per drain, latest values win 2026-08-16 04:02:20 -04:00
Joseph Doherty 2c708f5560 perf(mqtt): suppress unchanged-value republish fan-out 2026-08-15 21:42:00 -04:00
Joseph Doherty 8d91833fed feat(s7): pure narrow-scalar decode from byte spans 2026-08-15 21:41:46 -04:00
Joseph Doherty 6ff64ca067 perf(historian): group-commit batch append on the historization outbox 2026-08-15 21:40:04 -04:00
Joseph Doherty debd44c213 perf(acl): per-session decision-cache shards — a crawl no longer evicts the fleet 2026-08-15 21:38:48 -04:00
Joseph Doherty c3970a2e5d fix(modbus): dispose the previous transport and probe loops on re-initialize 2026-08-15 21:37:28 -04:00
Joseph Doherty 3122728593 test(runtime): serialize meter-asserting publish-actor suites (cross-collection counter pollution) 2026-08-15 18:16:59 -04:00
Joseph Doherty d787502d54 fix(opcuaserver): degraded applies re-diff instead of losing nodes; in-place UNS mirror updates; sever inverse edges
C1 — a non-rebuild apply reporting failedNodes > 0 no longer advances _lastApplied.
Pre-delta-materialisation the full passes re-ensured every node on every apply, which
silently repaired any prior swallowed sink fault. The delta path removed that accidental
self-healing: a failed node sat inside _lastApplied, never appeared in a diff set again,
and EnsureVariable early-returns on the ones that landed — so it was lost until an
unrelated change forced a rebuild. The advance also moved to AFTER the materialise
passes, so a throwing pass leaves _lastApplied at the previous composition too. A
rebuild still advances even with failures (the ratchet is its resync path).

I2 — a UnsReferenceDelta whose identity is unchanged (same NodeId, EquipmentId and
BackingRawPath) is now applied in place via UpdateTagAttributes(Uns) instead of
remove+recreate, so the mirror's MonitoredItems survive an operator historizing or
reshaping the raw tag behind them. Remove+recreate stays for identity-changing deltas
(re-point, effective-name edit).

I3 — RemoveVariableNode severs the inverse half of every outgoing Organizes edge, the
variable-node counterpart of UnwireAlarmNotifiers. Rebuilds used to sweep these up;
surgical applies made rebuilds rare, so they accumulated on the raw node for the life of
the process.

I5 — added UNS reference variables are announced (their equipment folder is the parent,
already the Uns realm). Raw adds still are not; the gap comment now says so honestly
rather than calling it neutral and pre-existing.

I4 + M1 — corrected two comments that no longer described the code: the "re-point →
rebuild" claim in ApplyPureRemove, and the "N lock acquisitions" rationale for the delta
passes (Ensure* early-return on a dictionary probe before the lock).
2026-08-15 17:53:26 -04:00
Joseph Doherty 0dbbb5ac6b fix(runtime): stash dedup + applying-wedge watchdog; cache-failure diagnostics 2026-08-15 17:43:15 -04:00
Joseph Doherty bfbdce32e4 perf(opcuaserver): non-rebuild applies materialise the delta, not the composition 2026-08-15 17:26:53 -04:00