fix(launcher): harden updater crash recovery

This commit is contained in:
Erik 2026-08-14 23:12:15 +02:00
parent 2d2a5b5046
commit 1955ca8ab5
27 changed files with 2714 additions and 544 deletions

View file

@ -44,6 +44,7 @@ public sealed class LauncherProcessSupervisorFactory(
/// </summary>
public sealed class LauncherProcessSupervisor : ILauncherProcessSupervisor
{
private static readonly TimeSpan DisposeStopTimeout = TimeSpan.FromSeconds(5);
private readonly ILauncherChildProcessFactory _factory;
private readonly object _gate = new();
private readonly Queue<LauncherSessionState> _pendingStateChanges = [];
@ -51,6 +52,7 @@ public sealed class LauncherProcessSupervisor : ILauncherProcessSupervisor
private LauncherSessionState _state = LauncherSessionState.Starting;
private int? _exitCode;
private bool _publishingStateChanges;
private bool _disposed;
public LauncherProcessSupervisor(ILauncherChildProcessFactory? factory = null)
{
@ -100,6 +102,7 @@ public sealed class LauncherProcessSupervisor : ILauncherProcessSupervisor
ILauncherChildProcess process;
lock (_gate)
{
ObjectDisposedException.ThrowIf(_disposed, this);
if (_process is not null)
{
throw new InvalidOperationException(
@ -201,6 +204,11 @@ public sealed class LauncherProcessSupervisor : ILauncherProcessSupervisor
if (!process.WaitForExit(timeout) && !process.HasExited)
{
process.Kill();
if (!process.WaitForExit(Timeout.InfiniteTimeSpan) && !process.HasExited)
{
throw new InvalidOperationException(
"The launcher child could not be observed terminal after it was killed.");
}
}
}
@ -307,6 +315,23 @@ public sealed class LauncherProcessSupervisor : ILauncherProcessSupervisor
public void Dispose()
{
ILauncherChildProcess? process;
lock (_gate)
{
if (_disposed)
{
return;
}
_disposed = true;
process = _process;
}
if (process is { HasExited: false })
{
Stop(DisposeStopTimeout);
}
lock (_gate)
{
if (_process is not null)