fix(probe): bound OpcUaClient/AbCip handshakes by timeout CTS; IPv4 preflight; stop sw (code-review)
This commit is contained in:
@@ -43,15 +43,18 @@ public sealed class OpcUaClientDriverProbe : IDriverProbe
|
||||
if (string.IsNullOrWhiteSpace(host) || port <= 0)
|
||||
return new(false, "Config has no host/port to probe.", null);
|
||||
|
||||
// Bound the whole probe (both phases) by the caller timeout, independent of `ct` — a
|
||||
// stalled OPC UA endpoint that accepts TCP but never answers GetEndpoints must not block
|
||||
// the probe when the caller passes CancellationToken.None.
|
||||
using var cts = CancellationTokenSource.CreateLinkedTokenSource(ct);
|
||||
cts.CancelAfter(timeout);
|
||||
|
||||
// --- TCP preflight: fast-fail for closed ports / unreachable hosts ---
|
||||
var sw = Stopwatch.StartNew();
|
||||
try
|
||||
{
|
||||
using var socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp)
|
||||
{
|
||||
DualMode = true,
|
||||
};
|
||||
await socket.ConnectAsync(host, port, ct);
|
||||
using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
await socket.ConnectAsync(host, port, cts.Token);
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
@@ -74,8 +77,8 @@ public sealed class OpcUaClientDriverProbe : IDriverProbe
|
||||
{
|
||||
var appConfig = BuildMinimalAppConfig();
|
||||
using var client = await DiscoveryClient.CreateAsync(
|
||||
appConfig, new Uri(endpointUrl), DiagnosticsMasks.None, ct).ConfigureAwait(false);
|
||||
var endpoints = await client.GetEndpointsAsync(null, ct).ConfigureAwait(false);
|
||||
appConfig, new Uri(endpointUrl), DiagnosticsMasks.None, cts.Token).ConfigureAwait(false);
|
||||
var endpoints = await client.GetEndpointsAsync(null, cts.Token).ConfigureAwait(false);
|
||||
sw.Stop();
|
||||
|
||||
if (endpoints is { Count: > 0 })
|
||||
|
||||
Reference in New Issue
Block a user