Skip to content

Commit 7d71c5d

Browse files
committed
fix(gateway): cap node reconnect wait timers
1 parent b135297 commit 7d71c5d

2 files changed

Lines changed: 24 additions & 2 deletions

File tree

src/gateway/server-methods/nodes.invoke-wake.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
22
import { ErrorCodes } from "../../../packages/gateway-protocol/src/index.js";
3+
import { MAX_TIMER_TIMEOUT_MS } from "../../shared/number-coercion.js";
34
import {
45
clearNodeWakeState,
56
maybeSendNodeWakeNudge,
67
maybeWakeNodeWithApns,
78
nodeHandlers,
9+
waitForNodeReconnect,
810
} from "./nodes.js";
911

1012
type MockNodeCommandPolicyParams = {
@@ -630,6 +632,25 @@ describe("node.invoke APNs wake path", () => {
630632
expectRecordFields(call[1], "respond payload", { ok: true, nodeId: "ios-node-reconnect" });
631633
});
632634

635+
it("caps oversized reconnect wait timers", async () => {
636+
vi.useFakeTimers();
637+
vi.setSystemTime(0);
638+
const nodeRegistry = {
639+
get: vi.fn(() => undefined),
640+
};
641+
642+
const reconnectPromise = waitForNodeReconnect({
643+
nodeId: "ios-node-never-reconnects",
644+
context: { nodeRegistry },
645+
timeoutMs: Number.MAX_SAFE_INTEGER,
646+
pollMs: Number.MAX_SAFE_INTEGER,
647+
});
648+
649+
await vi.advanceTimersByTimeAsync(MAX_TIMER_TIMEOUT_MS);
650+
await expect(reconnectPromise).resolves.toBe(false);
651+
expect(nodeRegistry.get).toHaveBeenCalledWith("ios-node-never-reconnects");
652+
});
653+
633654
it("broadcasts canonical Talk capture events for successful PTT node commands", async () => {
634655
const respond = vi.fn();
635656
const broadcast = vi.fn();

src/gateway/server-methods/nodes.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import {
3838
resolveApnsAuthConfigFromEnv,
3939
resolveApnsRelayConfigFromEnv,
4040
} from "../../infra/push-apns.js";
41+
import { resolveTimerTimeoutMs } from "../../shared/number-coercion.js";
4142
import {
4243
normalizeLowercaseStringOrEmpty,
4344
normalizeOptionalString,
@@ -672,8 +673,8 @@ export async function waitForNodeReconnect(params: {
672673
timeoutMs?: number;
673674
pollMs?: number;
674675
}): Promise<boolean> {
675-
const timeoutMs = Math.max(250, params.timeoutMs ?? NODE_WAKE_RECONNECT_WAIT_MS);
676-
const pollMs = Math.max(50, params.pollMs ?? NODE_WAKE_RECONNECT_POLL_MS);
676+
const timeoutMs = resolveTimerTimeoutMs(params.timeoutMs, NODE_WAKE_RECONNECT_WAIT_MS, 250);
677+
const pollMs = resolveTimerTimeoutMs(params.pollMs, NODE_WAKE_RECONNECT_POLL_MS, 50);
677678
const deadline = Date.now() + timeoutMs;
678679

679680
while (Date.now() < deadline) {

0 commit comments

Comments
 (0)