mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-20 23:54:26 +08:00
feat: implement launcher orchestrator and startup monitoring infrastructure for host lifecycle management
This commit is contained in:
@@ -19,12 +19,15 @@ internal sealed class AirAppRuntimeBridge
|
||||
|
||||
public async Task EnsureStartedAsync()
|
||||
{
|
||||
Logger.Info($"AIRAPP: Checking if AirApp Runtime is available. AppRoot='{_appRoot}'");
|
||||
|
||||
if (await TryGetStatusAsync().ConfigureAwait(false) is not null)
|
||||
{
|
||||
Logger.Info("AirApp Runtime is already available.");
|
||||
Logger.Info("AIRAPP: AirApp Runtime is already available.");
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.Info("AIRAPP: Starting AirApp Runtime...");
|
||||
Process? process;
|
||||
try
|
||||
{
|
||||
@@ -36,24 +39,28 @@ internal sealed class AirAppRuntimeBridge
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warn($"AirApp Runtime start request failed. AppRoot='{_appRoot}'; Error='{ex.Message}'.");
|
||||
Logger.Warn($"AIRAPP: AirApp Runtime start request failed. AppRoot='{_appRoot}'; Error='{ex.Message}'");
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.Info($"AirApp Runtime start requested. Pid={(process is null ? -1 : process.Id)}; AppRoot='{_appRoot}'.");
|
||||
Logger.Info($"AIRAPP: AirApp Runtime start requested. Pid={(process is null ? -1 : process.Id)}; AppRoot='{_appRoot}'.");
|
||||
|
||||
for (var attempt = 1; attempt <= ConnectAttempts; attempt++)
|
||||
{
|
||||
Logger.Info($"AIRAPP: Attempt {attempt}/{ConnectAttempts} - Checking IPC connection...");
|
||||
|
||||
if (await TryGetStatusAsync().ConfigureAwait(false) is not null)
|
||||
{
|
||||
Logger.Info("AirApp Runtime IPC is ready.");
|
||||
Logger.Info("AIRAPP: AirApp Runtime IPC is ready.");
|
||||
return;
|
||||
}
|
||||
|
||||
await Task.Delay(TimeSpan.FromMilliseconds(250 * attempt)).ConfigureAwait(false);
|
||||
var delayMs = 250 * attempt;
|
||||
Logger.Info($"AIRAPP: IPC not ready, waiting {delayMs}ms before retry...");
|
||||
await Task.Delay(TimeSpan.FromMilliseconds(delayMs)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
Logger.Warn("AirApp Runtime did not become ready after pre-start; Host fallback remains available.");
|
||||
Logger.Warn("AIRAPP: AirApp Runtime did not become ready after pre-start; Host fallback remains available.");
|
||||
}
|
||||
|
||||
public async Task AttachHostAsync(int hostProcessId)
|
||||
@@ -65,10 +72,15 @@ internal sealed class AirAppRuntimeBridge
|
||||
|
||||
try
|
||||
{
|
||||
using var cts = new CancellationTokenSource();
|
||||
using var client = new LanMountainDesktopIpcClient();
|
||||
await client.ConnectAsync(IpcConstants.AirAppRuntimePipeName).ConfigureAwait(false);
|
||||
|
||||
var connectTask = client.ConnectAsync(IpcConstants.AirAppRuntimePipeName);
|
||||
await connectTask.WaitAsync(TimeSpan.FromSeconds(3), cts.Token).ConfigureAwait(false);
|
||||
|
||||
var proxy = client.CreateProxy<IAirAppRuntimeControlService>();
|
||||
var result = await proxy.AttachHostAsync(hostProcessId).ConfigureAwait(false);
|
||||
var attachTask = proxy.AttachHostAsync(hostProcessId);
|
||||
var result = await attachTask.WaitAsync(TimeSpan.FromSeconds(3), cts.Token).ConfigureAwait(false);
|
||||
Logger.Info($"AirApp Runtime host attach completed. Accepted={result.Accepted}; Code='{result.Code}'; HostPid={hostProcessId}.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -81,13 +93,29 @@ internal sealed class AirAppRuntimeBridge
|
||||
{
|
||||
try
|
||||
{
|
||||
using var cts = new CancellationTokenSource();
|
||||
using var client = new LanMountainDesktopIpcClient();
|
||||
await client.ConnectAsync(IpcConstants.AirAppRuntimePipeName).ConfigureAwait(false);
|
||||
|
||||
var connectTask = client.ConnectAsync(IpcConstants.AirAppRuntimePipeName);
|
||||
await connectTask.WaitAsync(TimeSpan.FromSeconds(2), cts.Token).ConfigureAwait(false);
|
||||
|
||||
var proxy = client.CreateProxy<IAirAppRuntimeControlService>();
|
||||
return await proxy.GetStatusAsync().ConfigureAwait(false);
|
||||
var statusTask = proxy.GetStatusAsync();
|
||||
return await statusTask.WaitAsync(TimeSpan.FromSeconds(2), cts.Token).ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
catch (TimeoutException)
|
||||
{
|
||||
Logger.Info("AIRAPP: TryGetStatusAsync timed out (2s).");
|
||||
return null;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
Logger.Info("AIRAPP: TryGetStatusAsync cancelled.");
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Info($"AIRAPP: TryGetStatusAsync failed: {ex.GetType().Name} - {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user