fix(launcher): harden updater crash recovery
This commit is contained in:
parent
2d2a5b5046
commit
1955ca8ab5
27 changed files with 2714 additions and 544 deletions
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue