From c0ce125512d89ed15729200b32df313eba1267d8 Mon Sep 17 00:00:00 2001 From: Gustavo Madeira Santana Date: Sat, 28 Feb 2026 20:46:11 -0500 Subject: [PATCH] fix(gateway): shorten manual reinstall/restart delays MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LaunchAgent plist hardcodes ThrottleInterval to 60 in src/daemon/launchd-plist.ts That means every restart/install path that terminates the launchd-managed gateway gets delayed by launchd’s one-minute relaunch throttle. The CLI restart path in src/daemon/launchd.ts is doing the expected supervisor actions, but the plist policy makes those actions look hung. In src/daemon/launchd-plist.ts: - added LAUNCH_AGENT_THROTTLE_INTERVAL_SECONDS - reduced the LaunchAgent ThrottleInterval from 60 to 1 --- src/daemon/launchd-plist.ts | 7 ++++++- src/daemon/launchd.test.ts | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/daemon/launchd-plist.ts b/src/daemon/launchd-plist.ts index b292ff45974..37448cdcebf 100644 --- a/src/daemon/launchd-plist.ts +++ b/src/daemon/launchd-plist.ts @@ -1,5 +1,10 @@ import fs from "node:fs/promises"; +// launchd applies ThrottleInterval to any rapid relaunch, including +// intentional gateway restarts. Keep it low so CLI restarts and forced +// reinstalls do not stall for a full minute. +export const LAUNCH_AGENT_THROTTLE_INTERVAL_SECONDS = 1; + const plistEscape = (value: string): string => value .replaceAll("&", "&") @@ -106,5 +111,5 @@ export function buildLaunchAgentPlist({ ? `\n Comment\n ${plistEscape(comment.trim())}` : ""; const envXml = renderEnvDict(environment); - return `\n\n\n \n Label\n ${plistEscape(label)}\n ${commentXml}\n RunAtLoad\n \n KeepAlive\n \n ThrottleInterval\n 60\n ProgramArguments\n ${argsXml}\n \n ${workingDirXml}\n StandardOutPath\n ${plistEscape(stdoutPath)}\n StandardErrorPath\n ${plistEscape(stderrPath)}${envXml}\n \n\n`; + return `\n\n\n \n Label\n ${plistEscape(label)}\n ${commentXml}\n RunAtLoad\n \n KeepAlive\n \n ThrottleInterval\n ${LAUNCH_AGENT_THROTTLE_INTERVAL_SECONDS}\n ProgramArguments\n ${argsXml}\n \n ${workingDirXml}\n StandardOutPath\n ${plistEscape(stdoutPath)}\n StandardErrorPath\n ${plistEscape(stderrPath)}${envXml}\n \n\n`; } diff --git a/src/daemon/launchd.test.ts b/src/daemon/launchd.test.ts index 85c7a3350e9..6cf31dc5ce5 100644 --- a/src/daemon/launchd.test.ts +++ b/src/daemon/launchd.test.ts @@ -1,5 +1,6 @@ import { PassThrough } from "node:stream"; import { beforeEach, describe, expect, it, vi } from "vitest"; +import { LAUNCH_AGENT_THROTTLE_INTERVAL_SECONDS } from "./launchd-plist.js"; import { installLaunchAgent, isLaunchAgentListed, @@ -199,7 +200,7 @@ describe("launchd install", () => { expect(plist).toContain(""); expect(plist).not.toContain("SuccessfulExit"); expect(plist).toContain("ThrottleInterval"); - expect(plist).toContain("60"); + expect(plist).toContain(`${LAUNCH_AGENT_THROTTLE_INTERVAL_SECONDS}`); }); it("restarts LaunchAgent with bootout-bootstrap-kickstart order", async () => {