Add launcher coordinator IPC and startup reservation

Introduce a launcher coordinator to reserve startup ownership and prevent duplicate host launches. Adds a NamedPipe-based IPC server/client (LauncherCoordinatorIpcServer/Client), coordinator messages/models, and PublicShellStatus/activation types for richer shell reporting. Enhances StartupAttemptRecord and StartupAttemptRegistry to track coordinator pid/pipe, heartbeat, reserved-before-host-start, and public IPC status, plus new reservation/heartbeat APIs and takeover logic. Wire coordinator into App and LauncherFlowCoordinator to attach secondary launchers, publish coordinator status, probe existing hosts, and include more detailed launch result details. Also adds unit tests and docs describing coordinator and startup visuals behavior.
This commit is contained in:
lincube
2026-04-23 09:45:05 +08:00
parent 33591a0a63
commit 927dc8d1fd
19 changed files with 1637 additions and 23 deletions

View File

@@ -34,6 +34,7 @@ internal sealed class DesktopTrayService : IDisposable
private NativeMenuItem? _restartMenuItem;
private NativeMenuItem? _exitMenuItem;
private int _consecutiveRecoveryFailures;
private bool _disposed;
public DesktopTrayService(
Application application,
@@ -63,6 +64,14 @@ internal sealed class DesktopTrayService : IDisposable
public bool IsReady => State == TrayAvailabilityState.Ready;
public bool HasIcon => _trayIcon?.Icon is not null;
public bool HasMenu => _trayIcon?.Menu is not null;
public bool IsVisible => _trayIcon?.IsVisible == true;
public int ConsecutiveRecoveryFailures => _consecutiveRecoveryFailures;
public event Action<TrayAvailabilityState>? StateChanged;
public bool EnsureReady(string reason)
@@ -105,6 +114,7 @@ internal sealed class DesktopTrayService : IDisposable
public void Dispose()
{
_disposed = true;
StopWatchdog();
try
@@ -126,7 +136,7 @@ internal sealed class DesktopTrayService : IDisposable
_ = sender;
_ = e;
if (State == TrayAvailabilityState.Unavailable || State == TrayAvailabilityState.Failed)
if (_disposed || State == TrayAvailabilityState.Unavailable)
{
return;
}
@@ -256,6 +266,11 @@ internal sealed class DesktopTrayService : IDisposable
{
if (State == state)
{
if (state == TrayAvailabilityState.Failed)
{
StateChanged?.Invoke(state);
}
return;
}