Files

51 lines
1.3 KiB
TypeScript

export type ReadinessStatus = "ready" | "not-ready";
export interface ReadinessResult {
status: ReadinessStatus;
checks: Record<string, "ok" | "failed">;
}
async function withinTimeout(
check: () => Promise<unknown>,
timeoutMs: number,
): Promise<void> {
let timeout: ReturnType<typeof setTimeout> | undefined;
try {
await Promise.race([
check().then(() => undefined),
new Promise<never>((_, reject) => {
timeout = setTimeout(
() => reject(new Error("Dependency check timed out.")),
timeoutMs,
);
}),
]);
} finally {
if (timeout) clearTimeout(timeout);
}
}
export async function checkReadiness(
checks: Record<string, () => Promise<unknown>>,
timeoutMs = 2_500,
): Promise<ReadinessResult> {
const boundedTimeout = Math.max(100, Math.min(10_000, timeoutMs));
const entries = await Promise.all(
Object.entries(checks).map(async ([name, check]) => {
try {
await withinTimeout(check, boundedTimeout);
return [name, "ok"] as const;
} catch {
return [name, "failed"] as const;
}
}),
);
const result = Object.fromEntries(entries);
return {
status: Object.values(result).every((value) => value === "ok")
? "ready"
: "not-ready",
checks: result,
};
}