Merge branch 'master' into remed/lane-C

This commit is contained in:
Joseph Doherty
2026-10-22 13:31:03 -04:00
51 changed files with 3658 additions and 128 deletions
@@ -72,7 +72,13 @@ public sealed class TelemetryDialOptions
/// <summary>How often central refreshes its set of dialable node contacts, in seconds.</summary>
public int ContactRefreshSeconds { get; set; } = 60;
/// <summary>Per-call deadline for a gRPC telemetry dial, in seconds.</summary>
/// <summary>
/// Deadline, in seconds, for a gRPC telemetry dial to deliver its first event. A live node answers a
/// fresh subscribe at once (it replays its health/resilience snapshots), so a dial still silent at the
/// deadline is one that never connected — it is cancelled and re-dialled. Bounds establishment only;
/// an established stream is kept alive by HTTP/2 keepalive pings, not by this value. Values below 1
/// are treated as 1.
/// </summary>
public int CallTimeoutSeconds { get; set; } = 30;
}
@@ -188,6 +188,13 @@ public sealed class DiscoveryDriverBrowser : IUniversalDriverBrowser
}
}
/// <summary>
/// Final teardown of a throwaway capture/probe driver: a bounded <see cref="IDriver.ShutdownAsync"/>
/// followed by a bounded dispose. The dispose is NOT optional and runs even after a failed or timed-out
/// shutdown: a Galaxy driver's <c>ShutdownAsync</c> releases none of its gRPC runtime (channels, MX
/// session, stream loops) — only <c>DisposeAsync</c> does — so a browse that stopped at shutdown leaked a
/// full runtime per <c>/raw</c> browse and per <see cref="CanBrowse"/> probe (02/L1, 06/G-1).
/// </summary>
private async Task BoundedShutdownAsync(IDriver driver, string driverType)
{
try
@@ -199,7 +206,25 @@ public sealed class DiscoveryDriverBrowser : IUniversalDriverBrowser
catch (Exception ex)
{
_logger.LogWarning(ex,
"Browse-capture shutdown for {DriverType} failed/timed out; instance abandoned", driverType);
"Browse-capture shutdown for {DriverType} failed/timed out; disposing the instance anyway", driverType);
}
try
{
switch (driver)
{
case IAsyncDisposable asyncDisposable:
await asyncDisposable.DisposeAsync().AsTask().WaitAsync(_shutdownTimeout).ConfigureAwait(false);
break;
case IDisposable disposable:
disposable.Dispose();
break;
}
}
catch (Exception ex)
{
_logger.LogWarning(ex,
"Browse-capture dispose for {DriverType} failed/timed out; instance abandoned", driverType);
}
}
@@ -28,6 +28,10 @@
Directory.Packages.props. This is the one project where the DataProtection chain
enters the repo; every other consumer reaches it through a ProjectReference here. -->
<PackageReference Include="System.Security.Cryptography.Xml"/>
<!-- Surgical transitive pin — see the System.Security.Cryptography.Pkcs block in
Directory.Packages.props. Microsoft.Data.SqlClient (via EFCore.SqlServer) enters here
too and pulls a vulnerable Pkcs 9.0.4 wherever the shared framework prunes the Xml chain. -->
<PackageReference Include="System.Security.Cryptography.Pkcs"/>
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions"/>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions"/>
<PackageReference Include="Polly.Core"/>