🌳
pt0/deployF/k8sF/throwTimedOutAI.mts
5export const k8sWaitTimeoutMs = 90 * 1000 // 90 sec
6export const imagePullTimeoutMs = 10 * 60 * 1000 // ContainerCreating (first multi-GB image pull) budget; parity with k8s progressDeadlineSeconds default (600s)
8export const throwTimedOut = (startTime: number, label: string, timeoutMs: number = k8sWaitTimeoutMs) => {
9 const elapsedMs = Date.now() - startTime
10 if (elapsedMs <= timeoutMs) return
11 const elapsedSec = Math.round(elapsedMs / 1000)
12 const msg = `TIMEOUT ${label} after ${elapsedSec}s`
13 console.error(chalkRed(msg))
14 throwDebugH({label, elapsedSec})
17type PollUntilOpts = {
18 predicate: () => Promise<unknown> // truthy = keep waiting, falsy = done
19 intervalMs?: number
20 timeoutMs?: number
21 timeoutLabel: string
22 isQuiet?: boolean
25export const pollUntil = async ({predicate, intervalMs = 3000, timeoutMs, timeoutLabel, isQuiet}: PollUntilOpts) => {
26 const startTime = Date.now()
27 const effectiveTimeoutMs = timeoutMs ?? k8sWaitTimeoutMs
28 while (await predicate()) {
29 const elapsedMs = Date.now() - startTime
30 if (elapsedMs > effectiveTimeoutMs) {
31 const elapsedSec = Math.round(elapsedMs / 1000)
32 console.error(chalkRed(`TIMEOUT ${timeoutLabel} after ${elapsedSec}s`))
33 throwDebugH({timeoutLabel, elapsedSec})
34 }
35 if (!isQuiet) process.stdout.write('.')
36 await sleep(intervalMs)
37 }