Skip to content

Commit 165b2c6

Browse files
committed
fix(gateway): avoid default provider auth startup prewarm
1 parent e1a9817 commit 165b2c6

2 files changed

Lines changed: 81 additions & 24 deletions

File tree

src/gateway/server-startup-post-attach.test.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,59 @@ describe("startGatewayPostAttachRuntime", () => {
942942
}
943943
});
944944

945+
it("keeps provider auth failure rewarm without default startup prewarm", async () => {
946+
vi.useFakeTimers();
947+
const onGatewayLifetimeSidecars = vi.fn();
948+
const startupCfg = { marker: "startup" } as never;
949+
const afterFailureCfg = { marker: "after-failure" } as never;
950+
let currentCfg = startupCfg;
951+
const log = { info: vi.fn(), warn: vi.fn() };
952+
953+
try {
954+
await startGatewayPostAttachRuntime({
955+
...createPostAttachParams(),
956+
log,
957+
deferSidecars: true,
958+
providerAuthPrewarm: {
959+
delayMs: 1_000,
960+
getConfig: () => currentCfg,
961+
},
962+
onGatewayLifetimeSidecars,
963+
});
964+
965+
await vi.advanceTimersToNextTimerAsync();
966+
await vi.waitFor(() => {
967+
expect(onGatewayLifetimeSidecars).toHaveBeenCalledTimes(1);
968+
});
969+
expect(onGatewayLifetimeSidecars.mock.calls[0]?.[0]).toHaveLength(1);
970+
await vi.dynamicImportSettled();
971+
await vi.waitFor(() => {
972+
expect(hoisted.setAuthProfileFailureHook).toHaveBeenCalledTimes(1);
973+
});
974+
975+
await vi.advanceTimersByTimeAsync(1_000);
976+
expect(hoisted.warmCurrentProviderAuthStateOffMainThread).not.toHaveBeenCalled();
977+
978+
const hook = hoisted.setAuthProfileFailureHook.mock.calls[0]?.[0] as (() => void) | undefined;
979+
if (!hook) {
980+
throw new Error("Expected provider auth failure hook to be registered");
981+
}
982+
currentCfg = afterFailureCfg;
983+
hook();
984+
expect(hoisted.clearCurrentProviderAuthState).toHaveBeenCalledTimes(1);
985+
986+
await vi.advanceTimersByTimeAsync(1_000);
987+
await vi.waitFor(() => {
988+
expect(hoisted.warmCurrentProviderAuthStateOffMainThread).toHaveBeenCalledTimes(1);
989+
});
990+
expect(hoisted.warmCurrentProviderAuthStateOffMainThread.mock.calls[0]?.[0]).toBe(
991+
afterFailureCfg,
992+
);
993+
} finally {
994+
vi.useRealTimers();
995+
}
996+
});
997+
945998
it("keeps provider auth prewarm alive when Gmail post-ready sidecars stop", async () => {
946999
vi.useFakeTimers();
9471000
const onPostReadySidecars = vi.fn();

src/gateway/server-startup-post-attach.ts

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ function scheduleProviderAuthStatePrewarm(params: {
220220
warn: (msg: string) => void;
221221
};
222222
delayMs?: number;
223+
startupWarmEnabled?: boolean;
223224
}): GatewayPostReadySidecarHandle {
224225
let stopped = false;
225226
let startupTimer: ReturnType<typeof setTimeout> | undefined;
@@ -285,29 +286,31 @@ function scheduleProviderAuthStatePrewarm(params: {
285286
clearCurrentProviderAuthState();
286287
scheduleAuthMapRewarm("auth-profile-failure");
287288
});
288-
startupTimer = setTimeout(
289-
() => {
290-
void (async () => {
291-
if (isStopped()) {
292-
return;
293-
}
294-
const cfg = params.getConfig();
295-
const metrics = await measureProviderAuthWarm(() =>
296-
warmCurrentProviderAuthStateOffMainThread(cfg, { isCancelled: isStopped }),
297-
);
298-
if (isStopped()) {
299-
return;
300-
}
301-
params.log.info(
302-
`provider auth state pre-warmed ${formatProviderAuthWarmMetrics(metrics)}`,
303-
);
304-
})().catch((err) => {
305-
params.log.warn(`provider auth state pre-warm failed: ${String(err)}`);
306-
});
307-
},
308-
Math.max(0, delayMs),
309-
);
310-
startupTimer.unref?.();
289+
if (params.startupWarmEnabled !== false) {
290+
startupTimer = setTimeout(
291+
() => {
292+
void (async () => {
293+
if (isStopped()) {
294+
return;
295+
}
296+
const cfg = params.getConfig();
297+
const metrics = await measureProviderAuthWarm(() =>
298+
warmCurrentProviderAuthStateOffMainThread(cfg, { isCancelled: isStopped }),
299+
);
300+
if (isStopped()) {
301+
return;
302+
}
303+
params.log.info(
304+
`provider auth state pre-warmed ${formatProviderAuthWarmMetrics(metrics)}`,
305+
);
306+
})().catch((err) => {
307+
params.log.warn(`provider auth state pre-warm failed: ${String(err)}`);
308+
});
309+
},
310+
Math.max(0, delayMs),
311+
);
312+
startupTimer.unref?.();
313+
}
311314
})().catch((err) => {
312315
params.log.warn(`provider auth state pre-warm setup failed: ${String(err)}`);
313316
});
@@ -1255,12 +1258,13 @@ export async function startGatewayPostAttachRuntime(
12551258
}
12561259
const postReadySidecars = [...result.postReadySidecars];
12571260
const gatewayLifetimeSidecars: GatewayPostReadySidecarHandle[] = [];
1258-
if (params.providerAuthPrewarm?.enabled !== false) {
1261+
if (params.providerAuthPrewarm && params.providerAuthPrewarm.enabled !== false) {
12591262
gatewayLifetimeSidecars.push(
12601263
scheduleProviderAuthStatePrewarm({
12611264
getConfig: params.providerAuthPrewarm?.getConfig ?? (() => params.cfgAtStart),
12621265
log: params.log,
12631266
delayMs: params.providerAuthPrewarm?.delayMs,
1267+
startupWarmEnabled: params.providerAuthPrewarm.enabled === true,
12641268
}),
12651269
);
12661270
}

0 commit comments

Comments
 (0)