From 9ce4c92736743dee2efeafa7d1b5e4291ce1007e Mon Sep 17 00:00:00 2001 From: wood fish Date: Mon, 22 Jun 2026 17:44:16 +0800 Subject: [PATCH] fix(gateway): honor remote status probe timeout (#89859) Merged via squash. Prepared head SHA: 056707dbc76344a3d579eb7ffb21a0bf392fd283 Co-authored-by: mushuiyu886 <266724580+mushuiyu886@users.noreply.github.com> Co-authored-by: steipete <58493+steipete@users.noreply.github.com> Reviewed-by: @steipete --- src/commands/gateway-status.test.ts | 9 +++++++++ src/commands/gateway-status/helpers.test.ts | 14 ++++++++++++-- src/commands/gateway-status/helpers.ts | 12 ++++++------ 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/commands/gateway-status.test.ts b/src/commands/gateway-status.test.ts index 4bcc3f1e776..a0c524abaf5 100644 --- a/src/commands/gateway-status.test.ts +++ b/src/commands/gateway-status.test.ts @@ -983,6 +983,15 @@ describe("gateway-status command", () => { ]); }); + it("passes the full caller timeout through to active configured remote probes", async () => { + const { runtime } = createRuntimeCapture(); + probeGateway.mockClear(); + + await runGatewayStatus(runtime, { timeout: "15000", json: true }); + + expect(requireProbeCall("wss://remote.example:18789").timeoutMs).toBe(15_000); + }); + it("uses configured handshake timeout as the default local probe budget", async () => { const { runtime } = createRuntimeCapture(); probeGateway.mockClear(); diff --git a/src/commands/gateway-status/helpers.test.ts b/src/commands/gateway-status/helpers.test.ts index 7530153b3e7..22f5371ad1d 100644 --- a/src/commands/gateway-status/helpers.test.ts +++ b/src/commands/gateway-status/helpers.test.ts @@ -436,20 +436,30 @@ describe("resolveProbeBudgetMs", () => { ).toBe(2_500); }); - it("keeps non-local probe caps unchanged", () => { + it("lets active remote probes use the full caller budget", () => { expect( resolveProbeBudgetMs(15_000, { kind: "configRemote", active: true, url: "wss://gateway.example/ws", }), - ).toBe(1500); + ).toBe(15_000); expect( resolveProbeBudgetMs(15_000, { kind: "explicit", active: true, url: "wss://gateway.example/ws", }), + ).toBe(15_000); + }); + + it("keeps inactive remote and SSH tunnel probes on the short cap", () => { + expect( + resolveProbeBudgetMs(15_000, { + kind: "configRemote", + active: false, + url: "wss://gateway.example/ws", + }), ).toBe(1500); expect( resolveProbeBudgetMs(15_000, { diff --git a/src/commands/gateway-status/helpers.ts b/src/commands/gateway-status/helpers.ts index f1ece3974a9..24f51544fd5 100644 --- a/src/commands/gateway-status/helpers.ts +++ b/src/commands/gateway-status/helpers.ts @@ -150,15 +150,15 @@ export function resolveProbeBudgetMs( if (target.kind === "sshTunnel") { return Math.min(2000, overallMs); } + if (target.active) { + return overallMs; + } + if (target.kind === "localLoopback") { + return Math.min(800, overallMs); + } if (!isLoopbackProbeTarget(target)) { return Math.min(1500, overallMs); } - if (target.kind === "localLoopback" && !target.active) { - return Math.min(800, overallMs); - } - // Active/discovered loopback probes and explicit loopback URLs should honor - // the caller budget because healthy local detail RPCs can legitimately take - // longer than the legacy short caps. return overallMs; }