























@@ -1,3 +1,5 @@
1+// Measures gateway RPC round-trip time by launching an isolated local gateway
2+// and writing qa-lab-compatible summary artifacts.
13import { spawn } from "node:child_process";
24import { randomUUID } from "node:crypto";
35import { existsSync } from "node:fs";
@@ -10,7 +12,9 @@ import { fileURLToPath, pathToFileURL } from "node:url";
10121113const DEFAULT_METHODS = ["health", "config.get"];
1214const DEFAULT_ITERATIONS = 10;
15+/** Maximum time to wait for a spawned gateway to become reachable. */
1316export const READY_TIMEOUT_MS = 120_000;
17+/** Per-probe timeout used while polling gateway readiness endpoints. */
1418export const READY_PROBE_TIMEOUT_MS = 1_000;
1519const PARENT_TERMINATION_SIGNALS = ["SIGHUP", "SIGINT", "SIGTERM"];
1620const IS_DIRECT_RUN =
@@ -100,6 +104,9 @@ function formatErrorMessage(error) {
100104return String(error);
101105}
102106107+/**
108+ * Polls readiness endpoints while also failing fast if the child exits.
109+ */
103110export async function waitForGatewayReady({
104111 child,
105112 fetchImpl = fetch,
@@ -165,6 +172,9 @@ function resolveOpenClawLaunchArgs(repoRoot, sourceEntryExists = existsSync) {
165172return [path.join(repoRoot, "openclaw.mjs")];
166173}
167174175+/**
176+ * Signals the gateway process group on POSIX so spawned children are cleaned up.
177+ */
168178export function signalGatewayProcess(child, signal, killProcess = defaultKillProcess) {
169179if (process.platform !== "win32" && typeof child.pid === "number") {
170180try {
@@ -187,6 +197,9 @@ export function signalGatewayProcess(child, signal, killProcess = defaultKillPro
187197}
188198}
189199200+/**
201+ * Checks process-group liveness without treating an already-exited child as an error.
202+ */
190203export function isGatewayProcessAlive(child, killProcess = defaultKillProcess) {
191204if (process.platform !== "win32" && typeof child.pid === "number") {
192205try {
@@ -210,6 +223,9 @@ function signalGatewayProcessForParentExit(child, signal, killProcess) {
210223}
211224}
212225226+/**
227+ * Installs parent-process cleanup handlers for a spawned gateway.
228+ */
213229export function installGatewayParentCleanup(
214230child,
215231{ killProcess = defaultKillProcess, processLike = process } = {},
@@ -255,6 +271,9 @@ async function waitForGatewayExit(child, timeoutMs, killProcess = defaultKillPro
255271return !isGatewayProcessAlive(child, killProcess);
256272}
257273274+/**
275+ * Stops the gateway with SIGTERM first and SIGKILL after the grace window.
276+ */
258277export async function stopGateway(child, options = {}) {
259278if (!isGatewayProcessAlive(child, options.killProcess)) {
260279return;
@@ -275,6 +294,9 @@ async function closeFileHandles(handles) {
275294}
276295}
277296297+/**
298+ * Starts an isolated loopback gateway with temp HOME/state directories.
299+ */
278300export async function startGateway({
279301 configPath,
280302 env = process.env,
@@ -354,6 +376,9 @@ export async function startGateway({
354376return child;
355377}
356378379+/**
380+ * Removes the temporary root used by the RPC RTT probe.
381+ */
357382export async function cleanupTempRoot(tempRoot, { rmImpl = fs.rm } = {}) {
358383try {
359384await rmImpl(tempRoot, { force: true, recursive: true });
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。