fix(opcuaclient): wire ProbeTimeoutSeconds into the Test Connect probe (R06:O-4)
The knob was authored by the AdminUI and parsed, but consumed by nothing. It now caps the probe deadline (shorter of the caller's budget and the config; never extends it; 1 s floor), the same rule as the Galaxy probe. Refs #743 Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
This commit is contained in:
@@ -51,7 +51,8 @@ public sealed class OpcUaClientDriverProbe : IDriverProbe
|
||||
|
||||
// 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.
|
||||
// the probe when the caller passes CancellationToken.None. The config's ProbeTimeoutSeconds caps it (O-4).
|
||||
timeout = EffectiveTimeout(timeout, opts.ProbeTimeoutSeconds);
|
||||
using var cts = CancellationTokenSource.CreateLinkedTokenSource(ct);
|
||||
cts.CancelAfter(timeout);
|
||||
|
||||
@@ -106,6 +107,23 @@ public sealed class OpcUaClientDriverProbe : IDriverProbe
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// R06:O-4 — the deadline the probe actually runs under: the caller's budget, tightened by the config's
|
||||
/// <see cref="OpcUaClientDriverOptions.ProbeTimeoutSeconds"/> when that is positive and shorter (it can only
|
||||
/// shorten the budget — the caller's own deadline fires regardless). A non-positive caller budget is floored
|
||||
/// to 1 s so the probe runs briefly rather than cancelling before it starts. Same rule as the Galaxy probe.
|
||||
/// </summary>
|
||||
/// <param name="callerTimeout">The budget the host handed the probe.</param>
|
||||
/// <param name="configuredSeconds">The config's <c>ProbeTimeoutSeconds</c>; ignored when not positive.</param>
|
||||
/// <returns>The effective probe deadline.</returns>
|
||||
internal static TimeSpan EffectiveTimeout(TimeSpan callerTimeout, int configuredSeconds)
|
||||
{
|
||||
var caller = callerTimeout > TimeSpan.Zero ? callerTimeout : TimeSpan.FromSeconds(1);
|
||||
if (configuredSeconds <= 0) return caller;
|
||||
var configured = TimeSpan.FromSeconds(configuredSeconds);
|
||||
return configured < caller ? configured : caller;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a minimal <see cref="ApplicationConfiguration"/> suitable for unauthenticated
|
||||
/// discovery (GetEndpoints). No PKI stores, no session certificate — discovery traffic
|
||||
|
||||
Reference in New Issue
Block a user