mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-13 12:20:35 +00:00
fix(infra): land #29078 from @cathrynlavery with restart fallback
Co-authored-by: Cathryn Lavery <cathryn@littlemight.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { spawn } from "node:child_process";
|
||||
import { triggerOpenClawRestart } from "./restart.js";
|
||||
import { hasSupervisorHint } from "./supervisor-markers.js";
|
||||
|
||||
type RespawnMode = "spawned" | "supervised" | "disabled" | "failed";
|
||||
@@ -21,29 +22,6 @@ 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
|
||||
@@ -55,10 +33,16 @@ 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).
|
||||
// On macOS under launchd, actively kickstart the supervised service to
|
||||
// bypass ThrottleInterval delays for intentional restarts.
|
||||
if (process.platform === "darwin" && process.env.OPENCLAW_LAUNCHD_LABEL?.trim()) {
|
||||
schedulelaunchdKickstart(process.env.OPENCLAW_LAUNCHD_LABEL.trim());
|
||||
const restart = triggerOpenClawRestart();
|
||||
if (!restart.ok) {
|
||||
return {
|
||||
mode: "failed",
|
||||
detail: restart.detail ?? "launchctl kickstart failed",
|
||||
};
|
||||
}
|
||||
}
|
||||
return { mode: "supervised" };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user