mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-13 18:56:40 +00:00
fix(infra): actively kickstart launchd on supervised gateway restart
When an agent triggers a gateway restart in supervised mode, the process exits expecting launchd KeepAlive to respawn it. But ThrottleInterval (default 10s, or 60s on older installs) can delay or prevent restart. Now calls triggerOpenClawRestart() to issue an explicit launchctl kickstart before exiting, ensuring immediate respawn. Falls back to in-process restart if kickstart fails. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
committed by
Peter Steinberger
parent
ee2eaddeb3
commit
db67492a00
@@ -21,6 +21,29 @@ function isLikelySupervisedProcess(env: NodeJS.ProcessEnv = process.env): boolea
|
||||
return hasSupervisorHint(env);
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawn a detached `launchctl kickstart -k` to force an immediate launchd
|
||||
* restart, bypassing ThrottleInterval. The -k flag sends SIGTERM to the
|
||||
* current process, so this MUST be non-blocking (spawn, not spawnSync) to
|
||||
* avoid deadlocking — the gateway needs to be free to handle the signal
|
||||
* and exit so launchd can start the replacement.
|
||||
*/
|
||||
function schedulelaunchdKickstart(label: string): boolean {
|
||||
const uid = typeof process.getuid === "function" ? process.getuid() : undefined;
|
||||
const target = uid !== undefined ? `gui/${uid}/${label}` : label;
|
||||
try {
|
||||
const child = spawn("launchctl", ["kickstart", "-k", target], {
|
||||
detached: true,
|
||||
stdio: "ignore",
|
||||
});
|
||||
child.on("error", () => {}); // best-effort; suppress uncaught error event
|
||||
child.unref();
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to restart this process with a fresh PID.
|
||||
* - supervised environments (launchd/systemd): caller should exit and let supervisor restart
|
||||
@@ -32,6 +55,11 @@ export function restartGatewayProcessWithFreshPid(): GatewayRespawnResult {
|
||||
return { mode: "disabled" };
|
||||
}
|
||||
if (isLikelySupervisedProcess(process.env)) {
|
||||
// On macOS under launchd, fire a detached kickstart so launchd restarts
|
||||
// us immediately instead of waiting for ThrottleInterval (up to 60s).
|
||||
if (process.platform === "darwin" && process.env.OPENCLAW_LAUNCHD_LABEL?.trim()) {
|
||||
schedulelaunchdKickstart(process.env.OPENCLAW_LAUNCHD_LABEL.trim());
|
||||
}
|
||||
return { mode: "supervised" };
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user