Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 33x 33x 33x 33x 33x 33x 1x 21x 21x 21x 21x 21x 21x 21x 21x 21x 21x 20x 5x 5x 5x 5x 1x 1x 5x 21x 21x 21x 21x 21x 15x 15x 12x 10x 9x 8x 7x 6x 21x 21x 5x 5x 21x | import { z } from "zod"
import { readPrivateJson, writePrivateJson } from "../auth/privateFile"
const readinessSchema = z.object({
version: z.literal(1),
pid: z.number().int().positive(),
startedAt: z.number().finite(),
updatedAt: z.number().finite(),
state: z.enum(["starting", "ready", "unhealthy", "stopped"]),
})
export type ReadinessState = z.infer<typeof readinessSchema>
export async function writeReadiness(
path: string,
state: ReadinessState
): Promise<void> {
await writePrivateJson(path, readinessSchema.parse(state))
}
export async function checkReadiness(options: {
path: string
expectedPid: number
notBefore: number
now?: number
isAlive?: (pid: number) => boolean
}): Promise<boolean> {
const now = options.now ?? Date.now()
const alive =
options.isAlive ??
((pid) => {
try {
process.kill(pid, 0)
return true
} catch {
return false
}
})
try {
const value = await readPrivateJson(options.path, 4096)
const parsed = readinessSchema.safeParse(value)
if (!parsed.success) return false
const state = parsed.data
return (
state.state === "ready" &&
state.pid === options.expectedPid &&
state.startedAt >= options.notBefore &&
state.startedAt <= state.updatedAt &&
state.updatedAt <= now &&
now - state.updatedAt <= 90000 &&
alive(state.pid)
)
} catch {
return false
}
}
|