8 Commits

Author SHA1 Message Date
Joseph Doherty 92171a01ec fix(ablegacy): build-and-swap device/tag tables; teardown safe vs Dispose and abandoned init
Review 07 H13: _devices and _tagsByRawPath were plain dictionaries cleared and
refilled in place while the retained poll loop, the actor's GetHostStatuses and
server reads enumerated them. Both are now built locally and published by
reference under a lifecycle lock; teardown swaps in empty tables.

Lane A contract: ShutdownAsync and Dispose each retire a disjoint set of device
states, so Dispose running concurrently with a still-joining ShutdownAsync is
safe. A lifecycle epoch makes an InitializeAsync that the runtime abandoned
(overlapping the next ShutdownAsync) refuse to publish its tables, start probe
loops or write health. A runtime cached on an already-retired device state by an
in-flight read is disposed instead of leaked, and late reads/writes no longer
overwrite shutdown's health. Per-key semaphores are no longer disposed under
callers that may still hold them.

Refs #738
Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
2026-10-22 14:04:51 -04:00
Joseph Doherty 1affb4b613 refactor(ablegacy): confine libplctag to its adapter behind AbStatus/AbTransportException 2026-10-07 15:39:01 -04:00
Joseph Doherty 3878b51e97 v3(ablegacy): apply Modbus exemplar — RawTags delivery + RawPath mapper
- Rename AbLegacyEquipmentTagParser → AbLegacyTagDefinitionFactory; TryParse →
  FromTagConfig(tagConfig, rawPath, out def). Drop the leading-{ heuristic and the
  deviceHostAddress key; def.Name = rawPath. Add inverse ToTagConfig. Keep strict-enum
  guards + Inspect.
- Options: Tags(IReadOnlyList<AbLegacyTagDefinition>) → RawTags(IReadOnlyList<RawTagEntry>).
- Driver: _tagsByRawPath (Ordinal); byName-only resolver; build table from _options.RawTags
  via FromTagConfig, threading WriteIdempotent + resolving RawTagEntry.DeviceName to the
  owning device host (ResolveDeviceHost; TODO(v3 WaveC) for the live Device-row host).
  DiscoverAsync + family-profile validation iterate the built table. Probe picks its address
  from RawTags via the mapper.
- Factory: retire the pre-declared tag DTO path; bind List<RawTagEntry>? RawTags; keep Devices.
- Cli BuildOptions: deliver typed defs as RawTagEntry via ToTagConfig.
- Tests: AbLegacyRawTags helper; migrate Tags= → RawTags; parser tests → FromTagConfig;
  equipment-ref driver/ResolveHost tests re-authored as RawTagEntry + read by RawPath.

Driver+Contracts+Cli green; 213 driver + 36 Cli tests pass.
2026-07-15 20:09:46 -04:00
Joseph Doherty 098adf43d0 fix(ablegacy): dispose per-parent RMW locks on teardown (review symmetry)
DisposeRuntimes() now disposes and clears _rmwLocks, _creationLocks, and
_runtimeLocks so ReinitializeAsync/ShutdownAsync cycles don't orphan their
SemaphoreSlim instances. Mirrors the TwinCAT _bitRmwLocks fix already shipped.
2026-06-17 12:10:42 -04:00
Joseph Doherty c48f299994 test(ablegacy): bit write surfaces device rejection status (review)
Adds `Bit_write_surfaces_device_rejection_status` to AbLegacyBitRmwTests,
verifying that a non-zero libplctag status returned by the parent-word write
in WriteBitInWordAsync propagates as a non-Good OPC UA StatusCode rather than
being silently swallowed. Added a minimal `WriteStatusOverride` hook to
FakeAbLegacyTag (test-project-only) so the read half of the RMW still
returns 0/Good while the write half returns the seeded error code.
2026-06-17 12:02:10 -04:00
Joseph Doherty 5c6b7cd6f9 feat(ablegacy): B/I/O-file bit-within-word writes via existing RMW path 2026-06-17 11:54:03 -04:00
Joseph Doherty 64e3fbe035 docs: backfill XML documentation across 756 files
v2-ci / build (push) Failing after 1m43s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
Adds <summary>, <param>, <typeparam>, and <inheritdoc/> tags to public
members surfaced by commentchecker — resolves 5,847 of 5,869 issues
(99.6%) across three /fixdocs passes.
2026-05-28 08:10:17 -04:00
Joseph Doherty a25593a9c6 chore: organize solution into module folders (Core/Server/Drivers/Client/Tooling)
Group all 69 projects into category subfolders under src/ and tests/ so the
Rider Solution Explorer mirrors the module structure. Folders: Core, Server,
Drivers (with a nested Driver CLIs subfolder), Client, Tooling.

- Move every project folder on disk with git mv (history preserved as renames).
- Recompute relative paths in 57 .csproj files: cross-category ProjectReferences,
  the lib/ HintPath+None refs in Driver.Historian.Wonderware, and the external
  mxaccessgw refs in Driver.Galaxy and its test project.
- Rebuild ZB.MOM.WW.OtOpcUa.slnx with nested solution folders.
- Re-prefix project paths in functional scripts (e2e, compliance, smoke SQL,
  integration, install).

Build green (0 errors); unit tests pass. Docs left for a separate pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 01:55:28 -04:00