51 lines
1.3 KiB
TypeScript
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,
|
|
};
|
|
}
|