fix(daemon): address clanker review findings for kickstart restart

Bug 1 (high): replace fixed sleep 1 with caller-PID polling in both
kickstart and start-after-exit handoff modes. The helper now waits until
kill -0 $caller_pid fails before issuing launchctl kickstart -k.

Bug 2 (medium): gate enable+bootstrap fallback on isLaunchctlNotLoaded().
Only attempt re-registration when kickstart -k fails because the job is
absent; all other kickstart failures now re-throw the original error.

Follows up on 3c0fd3dffe.
Fixes #43311, #43406, #43035, #43049
This commit is contained in:
Robin Waslander
2026-03-12 02:16:24 +01:00
committed by GitHub
parent b7a37c2023
commit 841ee24340
11 changed files with 137 additions and 27 deletions

View File

@@ -27,6 +27,7 @@ import type {
GatewayServiceEnvArgs,
GatewayServiceInstallArgs,
GatewayServiceManageArgs,
GatewayServiceRestartResult,
} from "./service-types.js";
const LAUNCH_AGENT_DIR_MODE = 0o755;
@@ -447,7 +448,7 @@ export async function installLaunchAgent({
export async function restartLaunchAgent({
stdout,
env,
}: GatewayServiceControlArgs): Promise<void> {
}: GatewayServiceControlArgs): Promise<GatewayServiceRestartResult> {
const serviceEnv = env ?? (process.env as GatewayServiceEnv);
const domain = resolveGuiDomain();
const label = resolveLaunchAgentLabel({ env: serviceEnv });
@@ -461,6 +462,7 @@ export async function restartLaunchAgent({
const handoff = scheduleDetachedLaunchdRestartHandoff({
env: serviceEnv,
mode: "kickstart",
waitForPid: process.pid,
});
if (!handoff.ok) {
throw new Error(`launchd restart handoff failed: ${handoff.detail ?? "unknown error"}`);
@@ -472,7 +474,7 @@ export async function restartLaunchAgent({
throw err;
}
}
return;
return { outcome: "scheduled" };
}
const start = await execLaunchctl(["kickstart", "-k", serviceTarget]);
@@ -484,7 +486,11 @@ export async function restartLaunchAgent({
throw err;
}
}
return;
return { outcome: "completed" };
}
if (!isLaunchctlNotLoaded(start)) {
throw new Error(`launchctl kickstart failed: ${start.stderr || start.stdout}`.trim());
}
// If the service was previously booted out, re-register the plist and retry.
@@ -517,4 +523,5 @@ export async function restartLaunchAgent({
throw err;
}
}
return { outcome: "completed" };
}