fix(runtime): dispose drivers on final stop, bound PostStop shutdown (A1)
DriverInstanceActor.PostStop now bounds IDriver.ShutdownAsync by a shutdownTimeout (default 5 s, logged on overrun) and then disposes the driver (IAsyncDisposable preferred, else IDisposable) — but only on a real stop. PreRestart flags the restart so the PostStop it triggers skips the dispose, because a supervision restart re-uses the same driver object (Props closure) and the host re-initialises it. DiscoveryDriverBrowser disposes its throwaway capture/probe driver after the bounded shutdown, including after a failed or timed-out one. Review refs: 02/L1, 02/P4, 06/G-1 (host context), 07/L2. Refs #731 Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user