refactor: share daemon lifecycle restart helpers

This commit is contained in:
Peter Steinberger 2026-03-14 00:13:58 +00:00
parent f8efa30305
commit 2d39c50ee6
2 changed files with 44 additions and 48 deletions

View File

@ -339,6 +339,22 @@ export async function runServiceRestart(params: {
const { stdout, emit, fail } = createActionIO({ action: "restart", json });
const warnings: string[] = [];
let handledNotLoaded: NotLoadedActionResult | null = null;
const emitScheduledRestart = (
restartStatus: ReturnType<typeof describeGatewayServiceRestart>,
serviceLoaded: boolean,
) => {
emit({
ok: true,
result: restartStatus.daemonActionResult,
message: restartStatus.message,
service: buildDaemonServiceSnapshot(params.service, serviceLoaded),
warnings: warnings.length ? warnings : undefined,
});
if (!json) {
defaultRuntime.log(restartStatus.message);
}
return true;
};
const loaded = await resolveServiceLoadedOrFail({
serviceNoun: params.serviceNoun,
@ -423,34 +439,14 @@ export async function runServiceRestart(params: {
}
let restartStatus = describeGatewayServiceRestart(params.serviceNoun, restartResult);
if (restartStatus.scheduled) {
emit({
ok: true,
result: restartStatus.daemonActionResult,
message: restartStatus.message,
service: buildDaemonServiceSnapshot(params.service, loaded),
warnings: warnings.length ? warnings : undefined,
});
if (!json) {
defaultRuntime.log(restartStatus.message);
}
return true;
return emitScheduledRestart(restartStatus, loaded);
}
if (params.postRestartCheck) {
const postRestartResult = await params.postRestartCheck({ json, stdout, warnings, fail });
if (postRestartResult) {
restartStatus = describeGatewayServiceRestart(params.serviceNoun, postRestartResult);
if (restartStatus.scheduled) {
emit({
ok: true,
result: restartStatus.daemonActionResult,
message: restartStatus.message,
service: buildDaemonServiceSnapshot(params.service, loaded),
warnings: warnings.length ? warnings : undefined,
});
if (!json) {
defaultRuntime.log(restartStatus.message);
}
return true;
return emitScheduledRestart(restartStatus, loaded);
}
}
}

View File

@ -99,6 +99,29 @@ describe("runDaemonRestart health checks", () => {
let runDaemonRestart: (opts?: { json?: boolean }) => Promise<boolean>;
let runDaemonStop: (opts?: { json?: boolean }) => Promise<void>;
function mockUnmanagedRestart({
runPostRestartCheck = false,
}: {
runPostRestartCheck?: boolean;
} = {}) {
runServiceRestart.mockImplementation(
async (params: RestartParams & { onNotLoaded?: () => Promise<unknown> }) => {
await params.onNotLoaded?.();
if (runPostRestartCheck) {
await params.postRestartCheck?.({
json: Boolean(params.opts?.json),
stdout: process.stdout,
warnings: [],
fail: (message: string) => {
throw new Error(message);
},
});
}
return true;
},
);
}
beforeAll(async () => {
({ runDaemonRestart, runDaemonStop } = await import("./lifecycle.js"));
});
@ -234,20 +257,7 @@ describe("runDaemonRestart health checks", () => {
it("signals a single unmanaged gateway process on restart", async () => {
findVerifiedGatewayListenerPidsOnPortSync.mockReturnValue([4200]);
runServiceRestart.mockImplementation(
async (params: RestartParams & { onNotLoaded?: () => Promise<unknown> }) => {
await params.onNotLoaded?.();
await params.postRestartCheck?.({
json: Boolean(params.opts?.json),
stdout: process.stdout,
warnings: [],
fail: (message: string) => {
throw new Error(message);
},
});
return true;
},
);
mockUnmanagedRestart({ runPostRestartCheck: true });
await runDaemonRestart({ json: true });
@ -262,12 +272,7 @@ describe("runDaemonRestart health checks", () => {
it("fails unmanaged restart when multiple gateway listeners are present", async () => {
findVerifiedGatewayListenerPidsOnPortSync.mockReturnValue([4200, 4300]);
runServiceRestart.mockImplementation(
async (params: RestartParams & { onNotLoaded?: () => Promise<unknown> }) => {
await params.onNotLoaded?.();
return true;
},
);
mockUnmanagedRestart();
await expect(runDaemonRestart({ json: true })).rejects.toThrow(
"multiple gateway processes are listening on port 18789",
@ -281,12 +286,7 @@ describe("runDaemonRestart health checks", () => {
configSnapshot: { commands: { restart: false } },
});
isRestartEnabled.mockReturnValue(false);
runServiceRestart.mockImplementation(
async (params: RestartParams & { onNotLoaded?: () => Promise<unknown> }) => {
await params.onNotLoaded?.();
return true;
},
);
mockUnmanagedRestart();
await expect(runDaemonRestart({ json: true })).rejects.toThrow(
"Gateway restart is disabled in the running gateway config",