Gateway: stop and restart unmanaged listeners (#39355)

* Daemon: allow unmanaged gateway lifecycle fallback

* Status: fix service summary formatting

* Changelog: note unmanaged gateway lifecycle fallback

* Tests: cover unmanaged gateway lifecycle fallback

* Daemon: split unmanaged restart health checks

* Daemon: harden unmanaged gateway signaling

* Daemon: reject unmanaged restarts when disabled
This commit is contained in:
Vincent Koc
2026-03-07 21:20:29 -05:00
committed by GitHub
parent 4062aa5e5d
commit bf9c362129
6 changed files with 569 additions and 34 deletions

View File

@@ -40,10 +40,11 @@ vi.mock("../../runtime.js", () => ({
}));
let runServiceRestart: typeof import("./lifecycle-core.js").runServiceRestart;
let runServiceStop: typeof import("./lifecycle-core.js").runServiceStop;
describe("runServiceRestart token drift", () => {
beforeAll(async () => {
({ runServiceRestart } = await import("./lifecycle-core.js"));
({ runServiceRestart, runServiceStop } = await import("./lifecycle-core.js"));
});
beforeEach(() => {
@@ -130,4 +131,49 @@ describe("runServiceRestart token drift", () => {
const payload = JSON.parse(jsonLine ?? "{}") as { warnings?: string[] };
expect(payload.warnings).toBeUndefined();
});
it("emits stopped when an unmanaged process handles stop", async () => {
service.isLoaded.mockResolvedValue(false);
await runServiceStop({
serviceNoun: "Gateway",
service,
opts: { json: true },
onNotLoaded: async () => ({
result: "stopped",
message: "Gateway stop signal sent to unmanaged process on port 18789: 4200.",
}),
});
const jsonLine = runtimeLogs.find((line) => line.trim().startsWith("{"));
const payload = JSON.parse(jsonLine ?? "{}") as { result?: string; message?: string };
expect(payload.result).toBe("stopped");
expect(payload.message).toContain("unmanaged process");
expect(service.stop).not.toHaveBeenCalled();
});
it("runs restart health checks after an unmanaged restart signal", async () => {
const postRestartCheck = vi.fn(async () => {});
service.isLoaded.mockResolvedValue(false);
await runServiceRestart({
serviceNoun: "Gateway",
service,
renderStartHints: () => [],
opts: { json: true },
onNotLoaded: async () => ({
result: "restarted",
message: "Gateway restart signal sent to unmanaged process on port 18789: 4200.",
}),
postRestartCheck,
});
expect(postRestartCheck).toHaveBeenCalledTimes(1);
expect(service.restart).not.toHaveBeenCalled();
expect(service.readCommand).not.toHaveBeenCalled();
const jsonLine = runtimeLogs.find((line) => line.trim().startsWith("{"));
const payload = JSON.parse(jsonLine ?? "{}") as { result?: string; message?: string };
expect(payload.result).toBe("restarted");
expect(payload.message).toContain("unmanaged process");
});
});