Skip to content

Client: admission controls for automatic communication recovery of managed sessions - #4902

Closed
cristipogacean wants to merge 1 commit into
masterfrom
feature/recovery-admission
Closed

cristipogacean wants to merge 1 commit into
masterfrom
feature/recovery-admission

Conversation

@cristipogacean

@cristipogacean cristipogacean commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Description

Adds optional, additive admission controls for the automatic communication recovery of ManagedSession. They are available through ManagedSessionOptions, the fluent ManagedSessionBuilder and DI. The defaults keep today's behavior.

Option Meaning
KeepAliveFailureThreshold (default 1) Consecutive failed keep-alives required before automatic recovery starts. A healthy keep-alive resets the count. Must be at least 1.
ReconnectOnCommunicationFailure (default true) When false, communication failures do not start automatic recovery, and an exhausted recovery cycle is not re-armed. Initial connection retries and explicit ReconnectAsync keep working.
UseSharedChannelManager (default true) When false, the session uses its own transport even if the host registers a shared channel manager.

A shared channel manager recovers channels on its own, so it cannot honor per-session admission. Combining custom admission with a shared manager is rejected, not silently ignored:

  • at creation;
  • when a custom session factory returns a managed channel;
  • when a managed channel is passed to ReconnectAsync.

Fluent API: WithCommunicationRecovery(...) and WithoutChannelManager().

Integration with recent master changes

Documentation: docs/Sessions.md.

Related Issues

Checklist

  • I have signed the CLA and read the CONTRIBUTING doc.
  • I have added tests that prove my fix is effective or that my feature works and increased code coverage.
  • I have added all necessary documentation.
  • I have verified that my changes do not introduce (new) build or analyzer warnings.
  • I ran all tests locally using the UA.slnx solution against at least .net framework and .net 10, and all passed.
  • I fixed all failing and flaky tests in the CI pipelines and all CodeQL warnings.
  • I have addressed all PR feedback received.

Validation

Branch based on master at f3980f9e7. Release.

Command Result
dotnet build tests/Opc.Ua.Client.Tests/Opc.Ua.Client.Tests.csproj -c Release (CustomTestTarget=net10.0) Succeeded, 0 warnings
dotnet format whitespace <project> --verify-no-changes --include <changed files> No changes
dotnet test tests/Opc.Ua.Client.Tests/bin/Release/net10.0/Opc.Ua.Client.Tests.dll --filter "<recovery admission, builders, state machine, managed session, session, recovery, reconnect, channel manager, reverse connect fixtures>" (CustomTestTarget=net10.0) Passed: 897 passed, 0 failed, 2 skipped
dotnet test tests/Opc.Ua.Client.Tests/Opc.Ua.Client.Tests.csproj -c Release -f net10.0 --filter "TestCategory!=LongRunning&TestCategory!=Stress" (CustomTestTarget=net10.0) Passed: 3344 passed, 0 failed, 2 skipped
dotnet test tests/Opc.Ua.Sessions.Tests/Opc.Ua.Sessions.Tests.csproj -c Release -f net10.0 --filter "TestCategory!=LongRunning&TestCategory!=Stress" (CustomTestTarget=net10.0) Passed: 865 passed, 0 failed, 379 skipped
dotnet test tests/Opc.Ua.Client.Tests/Opc.Ua.Client.Tests.csproj -c Release -f net48 --filter "TestCategory!=LongRunning&TestCategory!=Stress" (CustomTestTarget=net48) Passed: 3348 passed, 0 failed, 3 skipped

Draft: the full UA.slnx matrix runs in CI.

Preserve default recovery while supporting consecutive keep-alive failure thresholds, disabled automatic communication recovery and explicit session-owned transports. Wire options, fluent APIs and DI; reject independent channel-manager recovery when it would bypass policy. Initial retries and manual reconnect remain available. Validation: 501 related net10 tests and 182 policy/builder/state-machine net48 tests passed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

Code coverage

✅ Coverage gate passed.

Check Result Threshold
✅ Project line rate 88.97% (453193/509367 lines) >= 70.00%
✅ Project branch rate 79.41% >= 60.00%
✅ Patch coverage 100.00% (63/63 changed lines) >= 60.00% (<= 100 changed lines, advisory)
ℹ️ Baseline delta (advisory) +15.37 pp 73.60% recorded

Coverage is above the recorded baseline - consider ratcheting coverage-thresholds.json.

Thresholds live in coverage-thresholds.json. Whole report before exclusions: line 88.29%, branch 78.75%.

@codecov

codecov Bot commented Oct 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.23810% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.36%. Comparing base (f3980f9) to head (728cdd5).

Files with missing lines Patch % Lines
src/Opc.Ua.Client/Fluent/ManagedSessionBuilder.cs 90.00% 0 Missing and 2 partials ⚠️
...c.Ua.Client/Fluent/OpcUaClientBuilderExtensions.cs 87.50% 0 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #4902   +/-   ##
=======================================
  Coverage   83.36%   83.36%           
=======================================
  Files        3504     3504           
  Lines      509312   509367   +55     
  Branches    86474    86487   +13     
=======================================
+ Hits       424587   424637   +50     
+ Misses      55938    55934    -4     
- Partials    28787    28796    +9     
Flag Coverage Δ
actions 83.36% <95.23%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/Opc.Ua.Client/Session/ManagedSession.cs 81.25% <100.00%> (+0.54%) ⬆️
src/Opc.Ua.Client/Session/ManagedSessionOptions.cs 76.92% <ø> (ø)
...Client/Session/Reconnect/ConnectionStateMachine.cs 87.50% <100.00%> (+0.75%) ⬆️
...c.Ua.Client/Fluent/OpcUaClientBuilderExtensions.cs 86.58% <87.50%> (+0.21%) ⬆️
src/Opc.Ua.Client/Fluent/ManagedSessionBuilder.cs 90.90% <90.00%> (-0.14%) ⬇️

... and 43 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Custom factories can return managed transports without populating Session.ChannelManager, bypassing admission validation and allowing independent recovery.

1 open issue
What changed in this PR

Adds optional communication-recovery admission controls to ManagedSession, addressing #4895 while preserving default behavior and compatibility with reverse-connection recovery.

Changes:

  • Adds a consecutive keep-alive failure threshold, automatic recovery toggle, and session-owned transport selection.
  • Exposes the controls through options, fluent configuration, and dependency injection, with validation for incompatible channel-manager configurations.
  • Documents recovery semantics and adds admission, retry, builder, and validation tests.
File Description
tests/​Opc.Ua.Client.Tests/​Session/​ManagedSessionRecoveryAdmissionTests.cs Tests admission thresholds, manual recovery, and transport restrictions.
tests/​Opc.Ua.Client.Tests/​Session/​ConnectionStateMachineTests.cs Tests recovery-cycle rearming with automatic recovery enabled or disabled.
tests/​Opc.Ua.Client.Tests/​ClientBuilder/​OpcUaClientBuilderTests.cs Tests option propagation and validation through dependency injection.
tests/​Opc.Ua.Client.Tests/​ClientBuilder/​ManagedSessionBuilderTests.cs Tests fluent defaults, transport selection, and invalid combinations.
src/​Opc.Ua.Client/​Session/​Reconnect/​ConnectionStateMachine.cs Makes recovery-cycle rearming configurable.
src/​Opc.Ua.Client/​Session/​ManagedSessionOptions.cs Defines the three admission and transport options.
src/​Opc.Ua.Client/​Session/​ManagedSession.cs Applies admission controls and validates transport compatibility.
src/​Opc.Ua.Client/​Fluent/​OpcUaClientBuilderExtensions.cs Wires options and validation into dependency injection.
src/​Opc.Ua.Client/​Fluent/​ManagedSessionBuilder.cs Adds fluent recovery and transport configuration.
docs/​Sessions.md Documents admission behavior, restrictions, and usage.

Review effort: Balanced

await managed.StateMachine
.WaitForConnectedAsync(ct)
.ConfigureAwait(false);
if (customAdmission && managed.InnerSession.ChannelManager != null)
@cristipogacean

Copy link
Copy Markdown
Contributor Author

Closing per the review discussion with @marcschier (2026-10-26): not needed in the stack. The consuming application will use the existing managed-session reconnect configuration (ReconnectPolicyOptions / IReconnectPolicy) instead of adding recovery-admission options.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Client: explicit admission controls for automatic communication recovery of managed sessions

2 participants