From a11d85183261e89254b616dae63e2a8dc80c005c Mon Sep 17 00:00:00 2001 From: Codex Date: Sun, 28 Jun 2026 01:45:42 +0000 Subject: [PATCH] fix: retry direct sentinel service probes --- scripts/src/hwlab-node-web-sentinel-cicd.ts | 36 ++++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/scripts/src/hwlab-node-web-sentinel-cicd.ts b/scripts/src/hwlab-node-web-sentinel-cicd.ts index 0cd1e548..8af155f1 100644 --- a/scripts/src/hwlab-node-web-sentinel-cicd.ts +++ b/scripts/src/hwlab-node-web-sentinel-cicd.ts @@ -3172,17 +3172,35 @@ function callSentinelServiceDirect(method: "GET" | "POST", pathWithQuery: string "const method = process.env.SENTINEL_METHOD || 'GET';", "const url = process.env.SENTINEL_URL || '';", "const body = Buffer.from(process.env.SENTINEL_BODY_B64 || '', 'base64').toString('utf8');", + "const attempts = Math.max(1, Number(process.env.SENTINEL_ATTEMPTS || '1') || 1);", + "const delayMs = Math.max(0, Number(process.env.SENTINEL_RETRY_DELAY_MS || '0') || 0);", "const headers = method === 'POST' ? { 'content-type': 'application/json' } : undefined;", - "fetch(url, { method, headers, body: method === 'POST' ? body : undefined }).then(async (response) => {", - " const text = await response.text();", - " process.stdout.write(text);", - " if (!response.ok) process.exit(22);", - "}).catch((error) => {", - " console.error(error && error.stack ? error.stack : String(error));", + "const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));", + "(async () => {", + " let lastError = null;", + " for (let attempt = 1; attempt <= attempts; attempt += 1) {", + " try {", + " const response = await fetch(url, { method, headers, body: method === 'POST' ? body : undefined });", + " const text = await response.text();", + " process.stdout.write(text);", + " if (!response.ok) process.exit(22);", + " process.exit(0);", + " } catch (error) {", + " lastError = error;", + " console.error(JSON.stringify({ attempt, attempts, code: error?.cause?.code ?? null, address: error?.cause?.address ?? null, valuesRedacted: true }));", + " if (attempt < attempts && delayMs > 0) await sleep(delayMs);", + " }", + " }", + " console.error(lastError && lastError.stack ? lastError.stack : String(lastError));", " process.exit(23);", + "})().catch((error) => {", + " console.error(error && error.stack ? error.stack : String(error));", + " process.exit(24);", "});", ].join(" "); - const attemptTimeoutSeconds = Math.max(5, Math.min(timeoutSeconds, method === "GET" ? 15 : 60)); + const attempts = method === "GET" ? 6 : 3; + const retryDelayMs = 1000; + const attemptTimeoutSeconds = Math.max(5, Math.min(timeoutSeconds, method === "GET" ? 20 : 70)); const result = runCommand(["node", "-e", fetchScript], repoRoot, { timeoutMs: attemptTimeoutSeconds * 1000, env: { @@ -3190,6 +3208,8 @@ function callSentinelServiceDirect(method: "GET" | "POST", pathWithQuery: string SENTINEL_METHOD: method, SENTINEL_URL: url, SENTINEL_BODY_B64: bodyB64, + SENTINEL_ATTEMPTS: String(attempts), + SENTINEL_RETRY_DELAY_MS: String(retryDelayMs), }, }); const parsed = parseJsonObject(result.stdout); @@ -3206,7 +3226,7 @@ function callSentinelServiceDirect(method: "GET" | "POST", pathWithQuery: string error: result.exitCode === 0 ? null : clipTail(`${result.stderr}${result.stdout}`, 1000), proxyPath: null, result: compactCommand(result), - attempts: [{ attempt: 1, ...compactCommand(result), parsedOk: parsed !== null, transport: "direct-service", valuesRedacted: true }], + attempts: [{ attempt: "1..n", maxAttempts: attempts, ...compactCommand(result), parsedOk: parsed !== null, transport: "direct-service", valuesRedacted: true }], transport: "direct-service", valuesRedacted: true, };