

























@@ -6,6 +6,11 @@ import { appendFileSync, existsSync, readFileSync, writeFileSync } from "node:fs
66import { copyFile, readFile, rm } from "node:fs/promises";
77import path from "node:path";
88import { pathToFileURL } from "node:url";
9+import {
10+addTimerTimeoutGraceMs,
11+clampTimerTimeoutMs,
12+finiteSecondsToTimerSafeMilliseconds,
13+} from "@openclaw/normalization-core/number-coercion";
914import {
1015die,
1116ensureValue,
@@ -121,8 +126,24 @@ interface NpmUpdateSummary {
121126const macosVmDefault = "macOS Tahoe";
122127const windowsVm = "Windows 11";
123128const linuxVmDefault = "Ubuntu 26.04";
129+130+function resolveRequiredTimerMs(timeoutMs: number): number {
131+return clampTimerTimeoutMs(timeoutMs) ?? 1;
132+}
133+134+function resolveOptionalTimerMs(timeoutMs: number | undefined): number | undefined {
135+return timeoutMs === undefined || timeoutMs <= 0 ? undefined : resolveRequiredTimerMs(timeoutMs);
136+}
137+138+function resolveSecondsTimerMs(timeoutSeconds: number): number {
139+return finiteSecondsToTimerSafeMilliseconds(timeoutSeconds) ?? 1;
140+}
141+124142const updateTimeoutSeconds = readPositiveIntEnv("OPENCLAW_PARALLELS_NPM_UPDATE_TIMEOUT_S", 1200);
125143const updateCleanupBackstopMs = 60_000;
144+const updateTimeoutMs = resolveSecondsTimerMs(updateTimeoutSeconds);
145+const updateWithCleanupTimeoutMs =
146+addTimerTimeoutGraceMs(updateTimeoutMs, updateCleanupBackstopMs) ?? 1;
126147const freshLaneTimeoutKillGraceMs = readPositiveIntEnv(
127148"OPENCLAW_PARALLELS_NPM_UPDATE_FRESH_TIMEOUT_KILL_GRACE_MS",
1281492_000,
@@ -133,7 +154,9 @@ let loggedExitCleanupInstalled = false;
133154134155export function freshLaneTimeoutMs(platform: Platform): number {
135156const defaultSeconds = platform === "windows" ? 90 * 60 : 75 * 60;
136-return readPositiveIntEnv("OPENCLAW_PARALLELS_NPM_UPDATE_FRESH_TIMEOUT_S", defaultSeconds) * 1000;
157+return resolveSecondsTimerMs(
158+readPositiveIntEnv("OPENCLAW_PARALLELS_NPM_UPDATE_FRESH_TIMEOUT_S", defaultSeconds),
159+);
137160}
138161139162export function spawnLoggedCommand(
@@ -161,19 +184,23 @@ export function spawnLoggedCommand(
161184appendFileSync(logPath, text, "utf8");
162185onOutput(text);
163186};
164-const timeoutMs = options.timeoutMs ?? 0;
187+const timeoutMs = resolveOptionalTimerMs(options.timeoutMs);
188+const timeoutKillGraceMs =
189+options.timeoutKillGraceMs === undefined
190+ ? resolveRequiredTimerMs(freshLaneTimeoutKillGraceMs)
191+ : resolveRequiredTimerMs(options.timeoutKillGraceMs);
165192const timeoutTimer =
166-timeoutMs > 0
193+timeoutMs !== undefined
167194 ? setTimeout(() => {
168195timedOut = true;
169196append(
170197`\n[${options.timeoutLabel ?? `${command} ${args.join(" ")}`} timed out after ${timeoutMs}ms]\n`,
171198);
172199signalLoggedChild(child, "SIGTERM");
173-forceKillAt = Date.now() + (options.timeoutKillGraceMs ?? freshLaneTimeoutKillGraceMs);
200+forceKillAt = Date.now() + timeoutKillGraceMs;
174201forceKillTimer = setTimeout(
175202() => signalLoggedChild(child, "SIGKILL"),
176-options.timeoutKillGraceMs ?? freshLaneTimeoutKillGraceMs,
203+timeoutKillGraceMs,
177204);
178205}, timeoutMs)
179206 : undefined;
@@ -208,7 +235,7 @@ export function spawnLoggedCommand(
208235if (timedOut) {
209236void finishTimedOutLoggedProcessTree(child, {
210237 forceKillAt,
211-timeoutKillGraceMs: options.timeoutKillGraceMs ?? freshLaneTimeoutKillGraceMs,
238+ timeoutKillGraceMs,
212239}).then(finish, finish);
213240return;
214241}
@@ -926,7 +953,7 @@ export class NpmUpdateSmoke {
926953 label,
927954run: ({ signal }) => fn({ append, logPath, signal }),
928955timeoutDescription: `${updateTimeoutSeconds}s plus cleanup backstop`,
929-timeoutMs: updateTimeoutSeconds * 1000 + updateCleanupBackstopMs,
956+timeoutMs: updateWithCleanupTimeoutMs,
930957writeLog: async () => undefined,
931958});
932959})().finally(() => {
@@ -937,15 +964,15 @@ export class NpmUpdateSmoke {
937964}
938965939966private async runMacosUpdate(ctx: UpdateJobContext): Promise<void> {
940-await this.guestMacos(this.updateScript("macos"), updateTimeoutSeconds * 1000, ctx);
967+await this.guestMacos(this.updateScript("macos"), updateTimeoutMs, ctx);
941968}
942969943970private runWindowsUpdate(ctx: UpdateJobContext): Promise<void> {
944-return this.guestWindows(this.updateScript("windows"), updateTimeoutSeconds * 1000, ctx);
971+return this.guestWindows(this.updateScript("windows"), updateTimeoutMs, ctx);
945972}
946973947974private async runLinuxUpdate(ctx: UpdateJobContext): Promise<void> {
948-await this.guestLinux(this.updateScript("linux"), updateTimeoutSeconds * 1000, ctx);
975+await this.guestLinux(this.updateScript("linux"), updateTimeoutMs, ctx);
949976}
950977951978private updateScript(platform: Platform): string {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。