Complete fluent node manager extensibility - #4418
Merged
marcschier merged 4 commits intoSep 5, 2026
Merged
Conversation
Add virtual node families, monitored-item lifecycle and custom creation hooks, subscription-gated polling, configuration access, and source-generator fixes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: afaa67c9-fc97-4185-a785-edd54a937d95
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The new monitored-source reconcile path awaits user callbacks while holding its internal async lock, which can cause deadlocks and operational stalls under real workloads.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR completes the fluent node-manager extensibility surface in Opc.Ua.Server and the model/source-generation tooling needed to support on-demand (virtual) address spaces plus richer monitored-item lifecycle customization, with corresponding tests and docs.
Changes:
- Added fluent support for virtual node families (cheap ownership predicates, async materialization, per-operation caching, custom browsing, and family-level callbacks).
- Added monitored-item pre-creation decisions (refuse/default/custom item) plus full lifecycle and async batch hooks, including subscription-gated polling sources.
- Improved source-generation behavior and diagnostics for
[NodeManager]namespace URI binding, plus typed builder/model composition fixes and documentation updates.
File summaries
| File | Description |
|---|---|
| tools/Opc.Ua.SourceGeneration/SourceGenerator.cs | Adds MODELGEN035 diagnostic descriptor for unresolved [NodeManager] namespace expressions. |
| tools/Opc.Ua.SourceGeneration/NodeManagerAttributeDiscovery.cs | Captures unresolved attribute expressions for [NodeManager] URI arguments. |
| tools/Opc.Ua.SourceGeneration/ModelCompilation.cs | Reports MODELGEN035 and suppresses emission when [NodeManager] URI expressions are unresolved. |
| tools/Opc.Ua.SourceGeneration/AnalyzerReleases.Unshipped.md | Documents new analyzer ID MODELGEN035. |
| tools/Opc.Ua.SourceGeneration.Core/Generators/NodeManagerTemplates.cs | Emits fully-qualified model composer invocation in generated node managers. |
| tools/Opc.Ua.SourceGeneration.Core/Generators/NodeManagerGenerator.cs | Plumbs model namespace/prefix to templates for qualified generation. |
| tools/Opc.Ua.SourceGeneration.Core/Generators/FluentBuilderGenerator.cs | Improves typed wrapper state resolution for objects (prefers concrete generated *State). |
| tests/Opc.Ua.SourceGeneration.Tests/ModelGeneratorTests.cs | Adds tests for MODELGEN035 and constant-resolution behavior. |
| tests/Opc.Ua.SourceGeneration.Core.Tests/Generators/NodeManagerGeneratorTests.cs | Updates generator tests and adds qualified composer assertion. |
| tests/Opc.Ua.SourceGeneration.Core.Tests/Generators/FluentBuilderGeneratorTests.cs | Adds test asserting object wrappers use concrete state types. |
| tests/Opc.Ua.Server.Tests/Fluent/VirtualNodeBuilderTests.cs | Adds coverage for virtual node family behavior and configuration retention. |
| tests/Opc.Ua.Server.Tests/Fluent/SimulationBuilderExtensionsTests.cs | Ensures Simulation(...) accepts typed builder facades. |
| tests/Opc.Ua.Server.Tests/Fluent/MonitoredItemFluentTests.cs | Adds tests for monitored-item pre-creation decisions, lifecycle hooks, and subscription-gated polling. |
| src/Opc.Ua.Server/NodeManager/MonitoredItem/SamplingGroupMonitoredItemManager.cs | Implements ICustomMonitoredItemManager custom monitored-item creation for sampling-group manager. |
| src/Opc.Ua.Server/NodeManager/MonitoredItem/MonitoredNodeMonitoredItemManager.cs | Implements ICustomMonitoredItemManager custom monitored-item creation for monitored-node manager. |
| src/Opc.Ua.Server/NodeManager/MonitoredItem/MonitoredItemCreateDecision.cs | Introduces decision/context types to refuse/default/customize monitored-item creation. |
| src/Opc.Ua.Server/NodeManager/MonitoredItem/ICustomMonitoredItemManager.cs | Adds internal interface + validation helper for stack-managed custom monitored items. |
| src/Opc.Ua.Server/NodeManager/AsyncCustomNodeManager.cs | Adds pre-creation decision hook, async batch hook, monitored-item attach/detach notifications, and history-read/update interception points. |
| src/Opc.Ua.Server/Fluent/VirtualNodeBuilder.cs | Adds fluent virtual node family builder and registration plumbing. |
| src/Opc.Ua.Server/Fluent/RuntimeValueBuilderExtensions.cs | Makes PollEvery work through typed builder facades via attached-builder resolution. |
| src/Opc.Ua.Server/Fluent/ReferenceBuilderExtensions.cs | Adds fluent monitored-item hook registration through reference builders. |
| src/Opc.Ua.Server/Fluent/NodeManagerBuilder.cs | Adds virtual-family registry and expands dispatcher with monitored-item routing + batch hooks. |
| src/Opc.Ua.Server/Fluent/NodeBuilder.cs | Adds new monitored-item lifecycle hook registrations on node builders. |
| src/Opc.Ua.Server/Fluent/MonitoredSourceRegistry.cs | Adds subscription-gated polling/lifecycle infrastructure for monitored sources. |
| src/Opc.Ua.Server/Fluent/MonitoredSourceBuilderExtensions.cs | Adds public fluent extensions for subscription-gated sources (OnFirstSubscriber/OnLastSubscriber/PollWhileMonitored). |
| src/Opc.Ua.Server/Fluent/MonitoredItemBuilderExtensions.cs | Adds manager-level async monitored-item batch hook extensions. |
| src/Opc.Ua.Server/Fluent/ISimulationBuilder.cs | Makes Simulation(...) work through typed builder facades via attached-builder resolution. |
| src/Opc.Ua.Server/Fluent/InstanceCreationBuilderExtensions.cs | Adds fluent monitored-item hook registration through instance-creation builders. |
| src/Opc.Ua.Server/Fluent/INodeBuilder.cs | Extends fluent node builder interface with monitored-item creation + lifecycle hook APIs. |
| src/Opc.Ua.Server/Fluent/IFluentDispatcher.cs | Extends dispatcher contract for pre-creation decisions, lifecycle routing, and batch hooks. |
| src/Opc.Ua.Server/Fluent/FluentNodeManagerBase.cs | Centralizes fluent lifecycle forwarding, virtual node resolution, startup configuration exposure, and monitored-source registry wiring. |
| src/Opc.Ua.Server/Fluent/FluentDelegates.cs | Adds delegate types for monitored-item lifecycle, pre-creation decisions, and monitored-source lifecycle. |
| src/Opc.Ua.Server/EventIds.cs | Allocates event-id block for monitored source registry logging. |
| docs/NodeManagers.md | Documents virtual node families, monitored-item creation/lifecycle, subscription-gated sources, typed builder compatibility, and MODELGEN035 behavior. |
Review details
- Files reviewed: 34/34 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Preserve registrations from startup and runtime fluent builders and dispatch through the matching builder. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: afaa67c9-fc97-4185-a785-edd54a937d95
romanett
approved these changes
Sep 4, 2026
Run lifecycle reconciliation outside the registration lock and cache per-node value updaters across polling changes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: afaa67c9-fc97-4185-a785-edd54a937d95
hansgschossmann
approved these changes
Sep 4, 2026
Wait for the asynchronous poll continuation after advancing fake time instead of assuming a fixed number of scheduler yields. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: afaa67c9-fc97-4185-a785-edd54a937d95
7 tasks
marcschier
added a commit
to marcschier/UA-.NETStandard
that referenced
this pull request
Sep 5, 2026
Integrate upstream master through 978e6d1, preserving startup lifecycle adoption, typed method arguments, and the fluent node manager changes from OPCFoundation#4418. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2bb8a834-7695-4ae6-84cb-2471c76d1b12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Complete the fluent node-manager extensibility surface needed by dynamic and externally backed address spaces.
This change:
ApplicationConfigurationto generated manager partials throughFluentNodeManagerBase;[NodeManager]namespace expressions asMODELGEN035instead of silently dropping them;Related Issues
Validation
Opc.Ua.Server.Testsonnet10.0: 4,886 passed, 5 skipped.Opc.Ua.SourceGeneration.Core.Testsonnet10.0: 3,807 passed, 8 skipped.Opc.Ua.SourceGeneration.Testsonnet10.0: 164 passed.net48.net10.0; 22 focused tests passed onnet48.net48and once onnet10.0.83c571423.appveyor.ymlwhitelists only theappveyorbranch; it did not execute this PR.UA.slnxbuilds successfully fornet10.0; affected project builds are warning-free.dotnet test UA.slnxinvocation is currently blocked by the solution's mixed VSTest/Microsoft.Testing.Platform configuration under the .NET 10 SDK, so the affected test projects were run individually.Checklist