mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-11 09:11:13 +00:00
fix(gateway): keep watch restarts in-process
This commit is contained in:
@@ -44,6 +44,9 @@ export async function runWatchMain(params = {}) {
|
||||
const watchSession = `${deps.now()}-${deps.process.pid}`;
|
||||
childEnv.OPENCLAW_WATCH_MODE = "1";
|
||||
childEnv.OPENCLAW_WATCH_SESSION = watchSession;
|
||||
// The watcher owns process restarts; keep SIGUSR1/config reloads in-process
|
||||
// so inherited launchd/systemd markers do not make the child exit and stall.
|
||||
childEnv.OPENCLAW_NO_RESPAWN = "1";
|
||||
if (deps.args.length > 0) {
|
||||
childEnv.OPENCLAW_WATCH_COMMAND = deps.args.join(" ");
|
||||
}
|
||||
|
||||
@@ -72,6 +72,19 @@ describe("restartGatewayProcessWithFreshPid", () => {
|
||||
expect(spawnMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("keeps OPENCLAW_NO_RESPAWN ahead of inherited supervisor hints", () => {
|
||||
clearSupervisorHints();
|
||||
setPlatform("darwin");
|
||||
process.env.OPENCLAW_NO_RESPAWN = "1";
|
||||
process.env.LAUNCH_JOB_LABEL = "ai.openclaw.gateway";
|
||||
|
||||
const result = restartGatewayProcessWithFreshPid();
|
||||
|
||||
expect(result).toEqual({ mode: "disabled" });
|
||||
expect(triggerOpenClawRestartMock).not.toHaveBeenCalled();
|
||||
expect(spawnMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("returns supervised when launchd hints are present on macOS (no kickstart)", () => {
|
||||
clearSupervisorHints();
|
||||
expectLaunchdSupervisedWithoutKickstart({ launchJobLabel: "ai.openclaw.gateway" });
|
||||
|
||||
@@ -76,6 +76,7 @@ describe("watch-node script", () => {
|
||||
PATH: "/usr/bin",
|
||||
OPENCLAW_WATCH_MODE: "1",
|
||||
OPENCLAW_WATCH_SESSION: "1700000000000-4242",
|
||||
OPENCLAW_NO_RESPAWN: "1",
|
||||
OPENCLAW_WATCH_COMMAND: "gateway --force",
|
||||
}),
|
||||
}),
|
||||
@@ -146,6 +147,38 @@ describe("watch-node script", () => {
|
||||
expect(fakeProcess.listenerCount("SIGTERM")).toBe(0);
|
||||
});
|
||||
|
||||
it("forces no-respawn for watch children even when supervisor hints are inherited", async () => {
|
||||
const { child, spawn, watcher, createWatcher, fakeProcess } = createWatchHarness();
|
||||
|
||||
const runPromise = runWatchMain({
|
||||
args: ["gateway", "--force"],
|
||||
createWatcher,
|
||||
env: {
|
||||
LAUNCH_JOB_LABEL: "ai.openclaw.gateway",
|
||||
PATH: "/usr/bin",
|
||||
},
|
||||
process: fakeProcess,
|
||||
spawn,
|
||||
});
|
||||
|
||||
expect(spawn).toHaveBeenCalledWith(
|
||||
"/usr/local/bin/node",
|
||||
["scripts/run-node.mjs", "gateway", "--force"],
|
||||
expect.objectContaining({
|
||||
env: expect.objectContaining({
|
||||
LAUNCH_JOB_LABEL: "ai.openclaw.gateway",
|
||||
OPENCLAW_NO_RESPAWN: "1",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
fakeProcess.emit("SIGINT");
|
||||
const exitCode = await runPromise;
|
||||
expect(exitCode).toBe(130);
|
||||
expect(child.kill).toHaveBeenCalledWith("SIGTERM");
|
||||
expect(watcher.close).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("ignores test-only changes and restarts on non-test source changes", async () => {
|
||||
const childA = Object.assign(new EventEmitter(), {
|
||||
kill: vi.fn(function () {
|
||||
|
||||
Reference in New Issue
Block a user