50 lines
1.5 KiB
TypeScript
50 lines
1.5 KiB
TypeScript
|
|
import type { IHealthResponse } from '../interfaces/api.ts';
|
||
|
|
import type { IContainerStatus } from '../interfaces/container.ts';
|
||
|
|
import type { IGpuInfo } from '../interfaces/gpu.ts';
|
||
|
|
|
||
|
|
export function buildHealthSnapshot(options: {
|
||
|
|
statuses: Map<string, IContainerStatus>;
|
||
|
|
modelCount: number;
|
||
|
|
gpus: IGpuInfo[];
|
||
|
|
startTime: number;
|
||
|
|
version: string;
|
||
|
|
}): IHealthResponse {
|
||
|
|
let status: 'ok' | 'degraded' | 'error' = 'ok';
|
||
|
|
const reasons = new Set<'unhealthy_container' | 'no_models_available' | 'gpu_detection_failed'>();
|
||
|
|
const containerHealth: Record<string, 'healthy' | 'unhealthy'> = {};
|
||
|
|
const gpuStatus: Record<string, 'available' | 'in_use' | 'error'> = {};
|
||
|
|
|
||
|
|
for (const [id, containerStatus] of options.statuses) {
|
||
|
|
if (containerStatus.running && containerStatus.health === 'healthy') {
|
||
|
|
containerHealth[id] = 'healthy';
|
||
|
|
} else {
|
||
|
|
containerHealth[id] = 'unhealthy';
|
||
|
|
status = 'degraded';
|
||
|
|
reasons.add('unhealthy_container');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for (const gpu of options.gpus) {
|
||
|
|
gpuStatus[gpu.id] = 'available';
|
||
|
|
}
|
||
|
|
|
||
|
|
if (options.modelCount === 0) {
|
||
|
|
status = 'degraded';
|
||
|
|
reasons.add('no_models_available');
|
||
|
|
}
|
||
|
|
|
||
|
|
return {
|
||
|
|
status,
|
||
|
|
reasons: Array.from(reasons),
|
||
|
|
version: options.version,
|
||
|
|
uptime: Math.floor((Date.now() - options.startTime) / 1000),
|
||
|
|
containers: options.statuses.size,
|
||
|
|
models: options.modelCount,
|
||
|
|
gpus: options.gpus.length,
|
||
|
|
details: {
|
||
|
|
containers: containerHealth,
|
||
|
|
gpus: gpuStatus,
|
||
|
|
},
|
||
|
|
};
|
||
|
|
}
|