mirror of https://github.com/OpenVidu/openvidu.git
70 lines
2.3 KiB
TypeScript
70 lines
2.3 KiB
TypeScript
import type { Db } from 'mongodb';
|
|
import * as z from 'zod';
|
|
|
|
import { type ReadyChecks, WriterSchemaStatus } from '@openvidu-dashboard/typings';
|
|
|
|
import { ApiError } from '../http/api-error.js';
|
|
import { readSchemaStatus } from '../schema/schema-status.js';
|
|
import type { RouteRegistry } from './route-registry.js';
|
|
|
|
export const READY_PING_TIMEOUT_MS = 2_000;
|
|
|
|
const healthSchema = z.object({ status: z.literal('ok'), version: z.string() }).meta({ id: 'HealthResponse' });
|
|
const readySchema = z
|
|
.object({
|
|
status: z.literal('ready'),
|
|
checks: z.object({ mongo: z.enum(['ok', 'error']), schema: z.enum(WriterSchemaStatus).optional() })
|
|
})
|
|
.meta({ id: 'ReadyResponse' });
|
|
|
|
/** MongoDB answers a ping within 2 s and the writer schema is not older than this dashboard reads. */
|
|
export async function readiness(db: Db): Promise<{ ready: boolean; checks: ReadyChecks }> {
|
|
try {
|
|
await db.command({ ping: 1 }, { timeoutMS: READY_PING_TIMEOUT_MS });
|
|
} catch {
|
|
return { ready: false, checks: { mongo: 'error' } };
|
|
}
|
|
|
|
const { status } = await readSchemaStatus(db);
|
|
|
|
return { ready: status !== WriterSchemaStatus.OLDER, checks: { mongo: 'ok', schema: status } };
|
|
}
|
|
|
|
/** `GET /health` (liveness, no MongoDB) and `GET /ready` (readiness). */
|
|
export function registerProbes(registry: RouteRegistry, version: string, db: Db): void {
|
|
registry.tag('Probes', 'Liveness and readiness of the dashboard, for orchestrators and load balancers');
|
|
registry.register({
|
|
method: 'get',
|
|
path: '/health',
|
|
operationId: 'getHealth',
|
|
edition: 'ce',
|
|
summary: 'Liveness: the process answers; MongoDB is not checked',
|
|
tags: ['Probes'],
|
|
security: 'public',
|
|
responses: { 200: { description: 'Alive', schema: healthSchema } },
|
|
handler: () => ({ status: 'ok', version })
|
|
});
|
|
registry.register({
|
|
method: 'get',
|
|
path: '/ready',
|
|
operationId: 'getReadiness',
|
|
edition: 'ce',
|
|
summary: 'Readiness: MongoDB answers and the writer schema is supported',
|
|
tags: ['Probes'],
|
|
security: 'public',
|
|
responses: {
|
|
200: { description: 'Ready', schema: readySchema },
|
|
503: { description: 'Not ready; details.checks says why' }
|
|
},
|
|
handler: async () => {
|
|
const { ready, checks } = await readiness(db);
|
|
|
|
if (!ready) {
|
|
throw new ApiError('NOT_READY', 'The dashboard is not ready', { checks });
|
|
}
|
|
|
|
return { status: 'ready', checks };
|
|
}
|
|
});
|
|
}
|