Harden HA address-space hydration and replica-consistent NodeIds - #4445
Merged
marcschier merged 15 commits intoSep 9, 2026
Merged
Conversation
Route transactional providers through their atomic update methods, preserve modified-history audit metadata, and add event plus structured-history client APIs with regression coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Implement all released Historical Access client/server facets, durable continuation takeover, truthful profile claims, complete reference workflows, and strongly consistent active/passive historian failover. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9dbd9527-d818-47a0-984c-fbb1472d3d6b
Treat ObjectDisposedException as part of best-effort HistoryRead continuation release so enumerator disposal cannot mask the original result. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9dbd9527-d818-47a0-984c-fbb1472d3d6b
Preserve the latest processed-history validation and output limits while retaining continuation-aware dispatch. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9dbd9527-d818-47a0-984c-fbb1472d3d6b
Close OPCFoundation#4400 by making aggregate revision provider-aware, gating processed reads, priming aggregate monitored items from raw history, and adding tri-state Historizing control. Preserve compatibility and durable required-error delivery. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9dbd9527-d818-47a0-984c-fbb1472d3d6b
Clarify continuation failover behavior, remove inapplicable migration and CTT wording, replace suppression workarounds, use Variant.From, and simplify the redundancy callback. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9dbd9527-d818-47a0-984c-fbb1472d3d6b
Capture pending ownership partitioning, authoritative hydration, sequenced store, and binary-state restoration work for integration with current master. Retain master test coverage rather than the superseded NativeAOT exclusion experiment. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9dbd9527-d818-47a0-984c-fbb1472d3d6b
Preserve the local ownership and authoritative-hydration work while retaining all completed historian fixes, namespace-zero exclusions, WoT reconciliation and NativeAOT partitions from master. Keep the discovered CRDT sequencing incompatibility visible as a draft blocker rather than inventing an unsafe CAS fallback. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9dbd9527-d818-47a0-984c-fbb1472d3d6b
Address OPCFoundation#4444 and OPCFoundation#4445 with explicit strong sequence/lease routing, protected publication reservations, validated snapshot publication, and strict authoritative record decoding. Retain real CRDT polling through shared hybrid coordination without fake CAS, private replicated counters, or unsafe snapshot/log compaction. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9dbd9527-d818-47a0-984c-fbb1472d3d6b
Reconcile authoritative root membership after sequence acceptance, retain values until topology exists, and exclude pre-deletion descendant values. Track node instances independently of mutable child links and await producer-owned snapshot cleanup during disposal. Document explicit strong versus eventual hydration and recovery contracts for OPCFoundation#4445. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9dbd9527-d818-47a0-984c-fbb1472d3d6b
Integrate master105508bcb before replica identity enforcement. Preserve WoT ownership partitions while adopting the shared factory and retaining async configure/seal and lifecycle/import ordering. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9dbd9527-d818-47a0-984c-fbb1472d3d6b
…ager changes Add the optional factory policy seam, awaited lifecycle preparation/rebinding, and cached address-space adapters that observe normal node-manager mutations without duplicating hydration notifications. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9dbd9527-d818-47a0-984c-fbb1472d3d6b
… live reload Bind fixed namespace and factory contracts to protected state and gossip admission. Preserve writer/retained identities, validate namespace-bearing metadata and structures, hydrate prepared managers and rebind capture, and exercise unchanged client IDs through real process failover, AddNodes, live reload, restart, and NativeAOT. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9dbd9527-d818-47a0-984c-fbb1472d3d6b
marcschier
marked this pull request as ready for review
September 9, 2026 04:59
Contributor
There was a problem hiding this comment.
🔵 Needs a closer look
It introduces broad, cross-cutting changes to HA replication/identity and lifecycle wiring that warrant maintainer review beyond targeted test evidence.
Pull request overview
This draft follow-up hardens redundant-server address-space replication by enforcing a replica-set NodeId identity contract (fixed shared namespace slots + policy-preserving factories) and by strengthening hydration/registration hooks so replicas keep identical wire NodeIds across failover and node-manager replacement.
Changes:
- Add replica identity plumbing (
INodeIdFactoryPolicy,ReplicaNodeIdFactoryintegration, ownership partitions) and validate identity/store/peer contracts early in startup and during lifecycle changes. - Harden runtime/hydration behavior (address-space ownership routing, in-place node updates, binary deserialization defaults for omitted attributes).
- Add targeted regression/integration tests plus samples/docs demonstrating identity-preserving client failover.
File summaries
| File | Description |
|---|---|
| tests/Opc.Ua.Types.Tests/State/NodeStateTests.cs | Assert binary-load defaults reset omitted attrs |
| tests/Opc.Ua.Types.Tests/State/MethodStateTests.cs | Assert omitted method flags deserialize deterministically |
| tests/Opc.Ua.Redundancy.Server.Tests/State/ReplicatedAddressSpaceStartupTaskTests.cs | Startup test updated for shared-namespace identity |
| tests/Opc.Ua.Redundancy.Server.Tests/Raft/RedundancyConsistencyBuilderExtensionsTests.cs | Strong-prefix routing regression for HA coordination |
| tests/Opc.Ua.Redundancy.Server.Tests/Identity/ReplicaNodeIdFactoryTests.cs | New: identity contract/unit coverage |
| tests/Opc.Ua.Redundancy.Server.Tests/Identity/ReplicaIdentityStoreTests.cs | New: protected store contract verification |
| tests/Opc.Ua.Redundancy.Server.Tests/Identity/ReplicaIdentityLifecycleTests.cs | New: replacement hydration + writer recapture regression |
| tests/Opc.Ua.Redundancy.Server.Tests/Identity/ReplicaIdentityGossipTests.cs | New: CRDT framing/admission identity tests |
| tests/Opc.Ua.Redundancy.Server.Tests/AddressSpace/DistributedAddressSpaceStartupTaskTests.cs | Ownership/partition seeding and failure-path coverage |
| tests/Opc.Ua.Redundancy.Samples.Tests/TestPorts.cs | Add adjacent-port selection helper for samples |
| tests/Opc.Ua.Redundancy.Samples.Tests/SampleHaShortHaulTests.cs | Add process-level identity failover scenario |
| tests/Opc.Ua.Redundancy.Samples.Tests/RedundantServerCluster.cs | Add active/active cluster boot helper |
| tests/Opc.Ua.Aot.Tests.Historian/ReplicaNodeIdentityAotTests.cs | New: NativeAOT identity/hydration proof |
| src/Opc.Ua.WotCon.Server/WotRegistryNodeManager.cs | Add explicit distributed ownership partitioning |
| src/Opc.Ua.WotCon.Server/WotConnectivityNodeManager.cs | Add explicit ownership + policy-aware factory mode |
| src/Opc.Ua.WotCon.Server/WotConModelPartition.cs | Expose NodeId-based partition helpers |
| src/Opc.Ua.Types/State/NodeState.cs | Apply binary-load defaults; add UpdateFrom helper |
| src/Opc.Ua.Types/Opc.Ua.Types.csproj | InternalsVisibleTo for redundancy server |
| src/Opc.Ua.Server/Server/StandardServer.cs | Policy-preserving NodeIdFactory replacement + pre-start task hook |
| src/Opc.Ua.Server/NodeManager/PredefinedNodesAddressSpace.cs | Track driving ops and add internal notify helpers |
| src/Opc.Ua.Server/NodeManager/Lifecycle/NodeManagerLifecycle.cs | Rebind identity around commit/publication flows |
| src/Opc.Ua.Server/NodeManager/INodeIdFactoryPolicy.cs | New: identity policy contract for factories/registration |
| src/Opc.Ua.Server/NodeManager/ILocalAddressSpaceSource.cs | Add ILocalAddressSpaceOwnership for explicit partitions |
| src/Opc.Ua.Server/NodeManager/AsyncCustomNodeManager.cs | Cache local address space; validate registration via policy; notify routing |
| src/Opc.Ua.Redundancy.Server/State/ReplicatedAddressSpaceStartupTask.cs | Add pre-start identity validation + shared partition routing |
| src/Opc.Ua.Redundancy.Server/State/ReplicaLocalAddressSpace.cs | New: route shared graph across partitions |
| src/Opc.Ua.Redundancy.Server/State/ReplicaIdentityStore.cs | New: protected identity-contract binding in store |
| src/Opc.Ua.Redundancy.Server/State/NodeStateSerializer.cs | Add in-place update helpers + descendant NodeId collection |
| src/Opc.Ua.Redundancy.Server/State/INodeStateStore.cs | Add internal store capability/probing interfaces |
| src/Opc.Ua.Redundancy.Server/State/DistributedAddressSpaceStartupTask.cs | Add pre-start validation and partitioned synchronizer start/stop |
| src/Opc.Ua.Redundancy.Server/State/AddressSpaceRegistration.cs | New: validate ownership contracts + partition ids |
| src/Opc.Ua.Redundancy.Server/ReplicatedServerBuilderExtensions.cs | Register replicated startup task as pre-start + startup |
| src/Opc.Ua.Redundancy.Server/Redundancy/ServiceLevelStartupTask.cs | Clamp service level to 0 on identity incompatibility |
| src/Opc.Ua.Redundancy.Server/NugetREADME.md | Document identity/ownership/consistency requirements |
| src/Opc.Ua.Redundancy.Server/Identity/ReplicaNodeIdentityBuilderExtensions.cs | New: DI wiring for replica identity factory/policy |
| src/Opc.Ua.Redundancy.Server/Identity/ReplicaNamespaceValidator.cs | New: namespace-bearing metadata validation via encoder contract |
| src/Opc.Ua.Redundancy.Server/DistributedServerBuilderExtensions.cs | Validate lease election config; contribute strong prefixes |
| samples/Redundancy/RedundantServer/README.md | Document replica-consistent identity behavior |
| samples/Redundancy/RedundantServer/Program.cs | Wire UseReplicaNodeIdentity based on HA mode |
| samples/Redundancy/RedundantServer/HaSampleNodeManager.cs | Add factory-assigned nodes used by identity proof |
| samples/Redundancy/RedundantClient/README.md | Document --identity scenario |
| samples/Redundancy/RedundantClient/Program.Identity.cs | New: cached-NodeId failover scenario implementation |
| samples/Redundancy/RedundantClient/Program.cs | Add --identity option and invoke scenario |
| docs/ReplicaNodeIdentity.md | New: end-to-end replica identity documentation |
| docs/README.md | Link new identity documentation |
| docs/NodeManagers.md | Document identity requirement for replicated managers |
| docs/NodeIdAssignment.md | Point redundant setups to UseReplicaNodeIdentity |
| docs/MigrationGuide.md | Add migration guidance for replica-consistent NodeIds |
| docs/HighAvailability.md | Document identity module + active/passive consistency constraints |
Review details
- Files reviewed: 56/56 changed files
- Comments generated: 4
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…ownership Notify listeners with the node actually registered by the add pipeline, reject missing or overflowing WoT ownership namespace indexes, and document retired-manager cleanup exceptions. Add regression coverage for replacement instances and namespace bounds. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9dbd9527-d818-47a0-984c-fbb1472d3d6b
marcschier
enabled auto-merge (squash)
September 9, 2026 10:25
hansgschossmann
approved these changes
Sep 9, 2026
romanett
added a commit
that referenced
this pull request
Sep 10, 2026
Conflict in HaSampleNodeManager.CreateAddressSpaceAsync, where #4445 added AddFactoryAssignedNodes next to the HistoryEvents object this branch had converted to the staged builder. Both are kept: the factory-assigned subtree stays hand-built and unstaged on purpose, because it exists to show what an identity minted straight through NodeIdFactory looks like beside the sample's named ones, and it is attached after the folder has been staged so those identifiers survive untouched. The merge also exposed a defect in this branch's New override. Naming every node after its browse name is too broad: a browse name is unique only among its siblings, and the historian hangs an "HA Configuration" object off each node it historizes, so the Counter's and the HistoryEvents' one both landed on ns=2;s=HA Configuration and the strong active/passive replicas refused to start. The override is now limited to the sample folder and its direct children - the nodes the redundant client spells out - and everything else keeps the default factory's derived identifier. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
marcschier
pushed a commit
that referenced
this pull request
Sep 10, 2026
…d-rolled node managers (#4460) Closes #4429. PR #4428 added the node-creation surface to `INodeManagerBuilder`. This picks up the remaining candidates that needed a base-class change first, and reports on the two that turn out not to be candidates at all. ## Converted **`samples/WotCon/FlatTagServer/FlatTagNodeManager.cs`** — now derives from `FluentNodeManagerBase`. The private `CreateObject` / `CreateVariable` / `CreateMethod` helpers are gone, along with every `pumpNodeId + ".Operational.Measurements.MassFlow"` concatenation; nodes are staged with `AddObject` / `AddVariable<T>` / `AddMethod` and the hand-maintained `externalReferences[ObjectsFolder]` entry is replaced by `CompleteConfigureAsync`. The `EventNotifier` bits and `AddRootNotifierAsync(pump)` are kept verbatim — the pump is the notifier an aggregating server subscribes to, and OPC 10000-3 only delivers the supervision conditions to a client that can reach one. `SupervisionSignal` loses its `namespaceIndex` and `tagPath` parameters and derives both from the supervision Object it hangs off, so the signal follows wherever that Object was staged. **`samples/Redundancy/RedundantServer/HaSampleNodeManager.cs`** — same shape. The `Counter` still reaches `EnableDistributedValueParticipation` through `INodeBuilder.Node`. The variables keep their `Organizes` reference type, which the fluent default would otherwise have made `HasComponent`. **`samples/DI/PumpDeviceIntegrationServer/OpenUsdComposition.cs`** — both `AddPredefinedNodeAsync` sites stage on the builder now, threaded through `ConfigureAsync`; `DiNodeManager.CreateAddressSpaceAsync` already calls `RegisterAuthoredNodesAsync` between `ConfigureAsync` and the reverse-reference pass, so no new plumbing was needed. Both methods became synchronous. The NodeIds are unchanged because the hand `SystemContext.NodeIdFactory.New(...)` calls and `AssignInstanceChildNodeIds` were already doing exactly what staging does. `CreateRepresentedComponent` is left alone: it sits on `CreatePumpAsync`, a public runtime API, and so is out of scope for the same reason as the DI device builders. ## NodeIds are part of two samples' contracts The issue expected the staged path to mint through the manager's `INodeIdFactory`, and it does — but for two of these samples the identifiers are a published contract, not an implementation detail: - the aggregating client's checked-in Thing Descriptions under `samples/WotCon/AggregationClient/Documents/` spell out `nsu=…SourceA;s=Pump1.Identification.Manufacturer`; - `samples/Redundancy/RedundantClient/Program.cs` addresses `new NodeId("Counter", ns)` directly. Both managers therefore override `New` for those nodes instead of taking the default factory's derived identifier, which satisfies the acceptance criterion that each manager keeps its current address-space shape. FlatTag mints the full dotted browse path; the HA sample mints the bare browse name, but only for the sample folder and its direct children. Two things are worth knowing for anyone writing such an override. **It has to keep an identifier the caller already chose.** `DefaultNodeIdFactory.New` returns `node.NodeId` unchanged when it is non-null and in the manager's own namespace. Without that same guard, `NodeState.Create(context, nodeId, …, assignNodeIds: true)` sets the explicit id and then `AssignNodeIds` overwrites it from the factory — which silently moved `…SupervisionProcessFluid.Cavitation.Alarm` to `…SupervisionProcessFluid.CavitationAlarm` and broke five alarm tests until the guard was added. **It has to be narrow.** A browse name is unique only among its siblings. The HA override originally named every node the manager minted, and the historian hangs an `HA Configuration` object off each node it historizes — so the Counter's and the HistoryEvents' one both landed on `ns=2;s=HA Configuration` and the strong active/passive replicas refused to start. It is now limited to the nodes the redundant client actually spells out. ## Merge with master Merged `origin/master` (`0e600c0f0`). The one conflict was in `HaSampleNodeManager.CreateAddressSpaceAsync`, where #4445 added `AddFactoryAssignedNodes` next to the `HistoryEvents` object this branch had converted. Both are kept, and the factory-assigned subtree stays hand-built and unstaged on purpose: it exists to show what an identity minted straight through `NodeIdFactory` looks like beside the sample's named ones. It is attached once the folder has been staged, so those identifiers survive untouched and the subtree is still registered as part of the folder's. Its parent's identifier is `s=HighAvailability` on both sides, so the ids it mints are unchanged from master. ## Not candidates **`src/Opc.Ua.PubSub.Server/PubSubNodeManager.cs`** is out for the issue's own DI-device-builder reasoning. All three of its build paths are reachable from runtime Method calls — `OnAddDataSetFolder` and `OnRemoveDataSetFolder` → `RebuildConfigurationAddressSpaceAsync`, `OnAddPushTarget` / `OnRemovePushTarget` → `RebuildKeyPushTargetAddressSpaceAsync`, `OnGetSecurityGroup` / `OnAddSecurityGroup` / `OnRemoveSecurityGroup` → `RebuildSecurityGroupAddressSpaceAsync` — plus `ConfigurationChanged`. Each removes its previous roots and rebuilds them, and `Add*` throws `BadInvalidState` once `RegisterAuthoredNodesAsync` has run. Independently of that, its parents (`PublishSubscribe`, `PublishedDataSets`, `SecurityGroups`, `KeyPushTargets`) are owned by the diagnostics node manager, so `AttachToParent` would reject them as `BadNodeIdUnknown`. **`src/Opc.Ua.OpenUsd.Server/Scene/UsdSceneMaterializer.Properties.cs`** — the issue asked whether a builder is reachable at those call sites. It is not. `MaterializeUsdStage` is a public, documented `ISystemContext` extension (`docs/OpenUsd.md`, the package README) whose only input is the context; it returns a detached subtree for the caller to register. It already mints through `context.RequireNodeIdFactory()`, which is the same factory the staged path uses, so there is nothing to gain and a public signature to break. ## Verification Run against the merged tree: - `Opc.Ua.Di.Tests` — 425/425 pass (covers `PumpOpenUsdE2eTests`, `PumpHostedReferenceTests`). - `Opc.Ua.Redundancy.Samples.Tests` — 14/14 pass, including both variants of master's new `FactoryAssignedNodeIdsSurviveActiveReplicaFailureAsync` and `StrongHistorianContinuationsSurviveActiveReplicaFailureAsync`. - `Opc.Ua.WotCon.Samples.Tests` — 25 pass, 4 fail. The same 4 fail on a clean baseline worktree (`CompanionTypeDefinitionsMatchNativePumpServerAsync`, `WotPumpInstanceMatchesNativePumpSubsetAsync`, `RealSamplesAggregateSubscribeAndReplaceGenerationAsync`, `RealSamplesRouteManagementAndConditionActionsToEachSourceAsync` — all `BadConfigurationError` out of the aggregation client). Pre-existing, unrelated to this change. - All three sample projects build with 0 warnings and 0 errors. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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
Follow-up to #4390 for distributed address-space ownership, authoritative
hydration, and replica-consistent wire NodeIds. Tracks #4444.
Identity implementation:
a78d59067(Server policy/lifecycle/adapter seam) and07faf5cfd(replica identity module, runtime wiring, examples and proofs).Replica identity
UseReplicaNodeIdentity/ReplicaNodeIdFactoryreserve fixed shared namespaceindexes before node-manager construction and reuse
DefaultNodeIdFactory.ApplicationUri and built-in diagnostics/configuration remain local.
deterministic mode, replica-set identity and writer policy must agree.
Standard factory views, replacement and registration preserve the policy.
creation requires stable keys or explicit IDs. Live IDs and retained tombstones
are reserved before writer allocation; no network/storage call runs in
New.prefixes. Unknown legacy state and empty eventual scans cannot authorize
automatic adoption. Verified-new hybrid provisioning is explicit.
are not reported as applied; incompatible admission remains at ServiceLevel 0
through the standard service-level wiring.
permissions, NodeId/ExpandedNodeId/QualifiedName values, arrays/matrices,
DataValues and encodeable structures/arguments, without reflection.
Rebinding keeps the existing store/election or gossip transport/map and attaches
to the new node-manager sources. Normal node-manager mutations, including
AddNodes, reach the cached local-address-space adapter.
genuinely factory-created nodes and a client
--identityfailover workflow.Preserved HA repairs
The published
d99995003and79da74f14fixes remain in place:private counter substituted for shared coordination.
snapshot publication and required delta retention.
cannot remove a newer incarnation.
snapshot task.
descendant values crossing incarnations.
A new deterministic regression also covers writer hydration preparation:
temporary reconciliation removals must remain inbound application, not be
recaptured as new shared deletion records.
Validation
Review feedback fixes
3a682155baddresses the active-node notification, WoT namespace-index bounds,and retired-manager XML documentation feedback. The address-space adapter now
notifies listeners with the registered active node, and both WoT managers reject
missing/out-of-range namespace indexes before ownership is established.
Targeted feedback validation passes on net10.0 and net48: 8 address-space adapter
cases and 74 WoT cases per framework, plus 17 hydration/gossip/live-client
integration cases on net10.0. The wrong-instance notification and missing
namespace regressions were reproduced before the fixes.
Identity implementation evidence
servers in all four deterministic modes, with different manager/creation order
and local allocations. Saved IDs work after endpoint failover and restart.
replacements in both replication modes, including nodes created after a reload.
verify a different serving ServerArray URI, and reuse cached factory-generated
IDs for Read and CreateMonitoredItems without remapping or rebrowsing.
executable in the existing historian companion host.
then passing. The real reload scenario was additionally repeated while
diagnosing that race.
CA1861 and CA1850 warnings in untouched upstream files were not suppressed.
The selected checks above do not replace full-solution CI, coverage gates or
maintainer review, and do not claim that the entire solution or every native
platform was run. #4444 remains the tracking issue.
Contract and consistency limits
Fixed identity does not make eventual payload reads linearizable. Hybrid views
remain non-destructive, use explicit tombstones, and do not infer empty-store
bootstrap or partition completion from absence. Compacted snapshots require
authoritative storage. Failed/uncertain reservations require reconciliation.
There is no automatic namespace-slot allocation, persistent logical-key mapping
database, live renumbering, legacy-store wipe/adoption, or new hash algorithm.
Opaque shared structures require a registered codec so their namespace-bearing
fields can be validated. Application callbacks are still application-owned.
Related issues
lifecycle/import (Fix startup NodeManager lifecycle and imported method arguments #4427) integration at
aedd3f738.Checklist