Make reverse connect lifecycle fully asynchronous#4059
Conversation
…verse-connect-lifecycle
…verse-connect-lifecycle
There was a problem hiding this comment.
Pull request overview
Note
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Makes reverse-connect startup/shutdown fully async across core + DI + samples, and expands tests/docs to cover cancellation, host integration, and restart/rollback scenarios.
Changes:
- Update test fixtures and integration tests to use
DisposeAsync/ async teardown patterns. - Add async DI lifecycle support (hosted service + async config provider model) and document migration path.
- Extend
ReverseConnectHostwith serialized async open/close/dispose behavior and add extensive concurrency/teardown tests.
Reviewed changes
Copilot reviewed 22 out of 24 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Opc.Ua.Sessions.Tests/WssReverseConnectIntegrationTests.cs | Switches fixture teardown to async disposal. |
| tests/Opc.Ua.Sessions.Tests/ReverseConnectTest.cs | Converts one-time teardown to async disposal. |
| tests/Opc.Ua.Sessions.Tests/KestrelTcpReverseConnectIntegrationTests.cs | Switches fixture teardown to async disposal. |
| tests/Opc.Ua.Core.Tests/Stack/Client/ReverseConnectHostTests.cs | Adds disposal + concurrency/serialization coverage for ReverseConnectHost. |
| tests/Opc.Ua.Client.Tests/ClientBuilder/ReverseConnectManagerTests.cs | Disables obsolete warnings to cover sync compatibility wrappers. |
| tests/Opc.Ua.Client.Tests/ClientBuilder/ClientReverseConnectOptionsTests.cs | Adds DI/host/lazy/eager startup + provider + restart overlay tests. |
| tests/Opc.Ua.Client.TestFramework/TestFixture.cs | Updates teardown to DisposeAsync. |
| tests/Opc.Ua.Client.TestFramework/ClientTestFramework.cs | Updates teardown to DisposeAsync. |
| tests/Opc.Ua.Client.TestFramework/ClientFixture.cs | Introduces IAsyncDisposable and async teardown path for fixtures. |
| tests/Opc.Ua.Aot.Tests/HostingAotTests.cs | Extends AOT coverage to resolve reverse-connect services. |
| src/Opc.Ua.Core/Stack/Client/ReverseConnectHost.cs | Adds IAsyncDisposable and serializes lifecycle operations with deterministic teardown. |
| src/Opc.Ua.Client/Opc.Ua.Client.csproj | Adds hosting abstractions reference for hosted-service integration. |
| src/Opc.Ua.Client/NugetREADME.md | Documents async reverse-connect lifecycle + DI behavior. |
| src/Opc.Ua.Client/IReverseConnectConfigurationProvider.cs | Adds injectable async configuration provider API + default pass-through impl. |
| src/Opc.Ua.Client/Fluent/ReverseConnectManagerHostedService.cs | Adds hosted service to eagerly start/stop manager under Generic Host. |
| src/Opc.Ua.Client/Fluent/OpcUaClientOptions.cs | Updates options docs to reflect eager/lazy async startup. |
| src/Opc.Ua.Client/Fluent/OpcUaClientBuilderExtensions.cs | Registers provider + hosted service; updates manager activator for async startup model. |
| src/Opc.Ua.Client/Fluent/ClientReverseConnectOptions.cs | Updates docs to describe hosted + lazy startup behavior. |
| samples/ConsoleReferenceClient/Program.cs | Migrates sample to StartServiceAsync / DisposeAsync. |
| docs/migrate/2.0.x/transport-listener-async.md | Documents new async reverse-connect lifecycle + migration steps. |
| docs/migrate/2.0.x/README.md | Updates migration index entry to include reverse-connect changes. |
| docs/ReverseConnect.md | Updates canonical reverse-connect docs for async + DI/provider lifecycle. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #4059 +/- ##
===========================================
- Coverage 73.86% 41.37% -32.50%
===========================================
Files 1345 945 -400
Lines 180038 133132 -46906
Branches 31678 24193 -7485
===========================================
- Hits 132993 55082 -77911
- Misses 36290 71382 +35092
+ Partials 10755 6668 -4087
🚀 New features to boost your workflow:
|
| protected virtual void OnUpdateConfiguration(ApplicationConfiguration configuration) | ||
| /// <exception cref="ArgumentNullException"><paramref name="endpointUrl"/> is <c>null</c>.</exception> | ||
| /// <exception cref="ServiceResultException"></exception> | ||
| public void AddEndpoint(Uri endpointUrl) |
There was a problem hiding this comment.
Removing both overloads of protected virtual OnUpdateConfiguration violates the repo rule: "Maintain compatibility with 1.5.378 … mark any replaced API with [Obsolete] . Already marked [Obsolete] API in 1.5.378 can be removed/replaced in master."
Neither overload was [Obsolete] in 1.5.378, so any external subclass overriding them will fail with CS0115 on 2.0.x.
There was a problem hiding this comment.
True for "callable" API, however, for "override extensibility" (e.g. virtual or interface changes) we almost always opted to "hard-replace" rather than maintaining the ability to implement/override. Because like in this case - we would not call the sync override when the async one is already doing the default. The use case for overriding ReverseConnectManager is anyway limited. Also - the rule is to make all implementations sealed, and only provide "provider/extensibilty" via interface or abstract classes. Which means in this case - if we are already making the change, we should probably make ReverseConnectManager "sealed" and expose a IReverseConnectManager interface to inject if the default behavior is not palatable.
…verse-connect-lifecycle
Summary
ReverseConnectManagerReverseConnectHostlifecycle and extend raw TCP, Kestrel TCP, WSS, hosting, concurrency, rollback, and NativeAOT coverageValidation
Opc.Ua.ClientRelease build across all supported target frameworksCloses #4013.
Related: #3985, #4009.