mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-20 23:54:26 +08:00
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:
@@ -40,7 +40,7 @@ Current built-in `[IpcPublic]` contracts:
|
||||
- `IPublicAppInfoService`
|
||||
- Returns application metadata such as version, codename, process id, pipe name, and startup time.
|
||||
- `IPublicShellControlService`
|
||||
- Allows external .NET clients to activate the shell, open settings, request restart, and request exit.
|
||||
- Allows external .NET clients to query shell status, activate the shell, repair tray readiness, repair taskbar entry visibility, open settings, request restart, and request exit.
|
||||
- `IPublicPluginCatalogService`
|
||||
- Returns the merged public IPC catalog snapshot exposed by Host.
|
||||
|
||||
@@ -77,6 +77,8 @@ Launcher no longer depends on the previous custom named-pipe length-prefixed pro
|
||||
|
||||
This means Splash/OOBE is now just another IPC consumer on the same base transport used by external integrators.
|
||||
|
||||
Launcher-to-launcher de-duplication is intentionally separate from Host Public IPC. The active Launcher coordinator uses a per-user local pipe and `startup-attempt.json` heartbeat so secondary Launchers attach to the coordinator before any host process can be started twice.
|
||||
|
||||
## Plugin Public IPC Contribution Model
|
||||
|
||||
Plugins can contribute new external IPC services in two ways:
|
||||
|
||||
@@ -569,3 +569,7 @@ Launcher now consumes Host startup telemetry from the unified public IPC stack:
|
||||
- Launcher connects through `LanMountainDesktopIpcClient`
|
||||
|
||||
The previous custom length-prefixed named-pipe transport is no longer the primary startup communication path.
|
||||
|
||||
## Coordinator Guard
|
||||
|
||||
Launcher also owns a small per-user local coordinator used only between Launcher processes. It reserves `startup-attempt.json` before host launch, publishes a heartbeat, and exposes a local coordinator pipe for secondary Launchers. A secondary Launcher must attach to that coordinator or activate the existing Host through Public IPC instead of starting another Host process. See [Launcher Coordinator](LAUNCHER_COORDINATOR.md).
|
||||
|
||||
31
docs/LAUNCHER_COORDINATOR.md
Normal file
31
docs/LAUNCHER_COORDINATOR.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Launcher Coordinator
|
||||
|
||||
LanMountainDesktop Launcher uses a per-user coordinator to prevent duplicate host startup.
|
||||
|
||||
## Rules
|
||||
|
||||
- A Launcher reserves `%LocalAppData%\LanMountainDesktop\.launcher\state\startup-attempt.json` before starting the host.
|
||||
- The active record stores coordinator pid, coordinator pipe name, heartbeat, host pid, Public IPC state, and shell status.
|
||||
- Only the active coordinator may start the host process.
|
||||
- Secondary Launchers attach to the coordinator and request desktop activation.
|
||||
- A coordinator is considered live while its pid exists and its heartbeat is newer than `10s`.
|
||||
- Normal launch probes Host Public IPC first; if the host is already running, Launcher activates it and exits.
|
||||
|
||||
## Tray And Taskbar
|
||||
|
||||
- Tray icon and tray menu are mandatory and are not controlled by user settings.
|
||||
- Tray watchdog starts with the shell and runs until process exit.
|
||||
- `ShowInTaskbar=true` affects only the main-window taskbar entry.
|
||||
- When `ShowInTaskbar=true`, background mode uses a minimized taskbar entry while keeping tray visible.
|
||||
- Pure `TrayOnly` is allowed only when `ShowInTaskbar=false` and tray is ready.
|
||||
|
||||
## Public Shell IPC
|
||||
|
||||
Launcher and external callers can use:
|
||||
|
||||
- `GetShellStatusAsync()`
|
||||
- `ActivateMainWindowWithStatusAsync()`
|
||||
- `EnsureTrayReadyAsync()`
|
||||
- `EnsureTaskbarEntryAsync()`
|
||||
|
||||
These APIs report process, shell, tray, taskbar, and activation state separately so callers do not infer health from window visibility alone.
|
||||
Reference in New Issue
Block a user