import http from "http"; /** * Запускает HTTP-сервер для проверки здоровья. * @param controller - AbortController для управления состоянием здоровья. * @param defaultPort - Порт для сервера по умолчанию (если не указан в ENV HEALTH_PORT). * @param defaultHostName - Имя хоста для сервера по умолчанию (если не указан в ENV HEALTH_HOST). */ export function createHealthServer( controller: AbortController, defaultPort: number = 8000, defaultHostName: string = "127.0.0.1", ) { const port = parseInt(process.env.HEALTH_PORT || `${defaultPort}`, 10); const hostname = process.env.HEALTH_HOST || defaultHostName; const server = http.createServer((req, res) => { if (req.url === "/health") { const signal = controller.signal; // Если сигнал отмены активирован, сервер помечается как "unhealthy" if (signal.aborted) { res.writeHead(500, { "Content-Type": "application/json" }); res.end( JSON.stringify({ status: "unhealthy", reason: "Service aborted", }), ); return; } // Возвращаем стандартный статус "ok", если всё нормально res.writeHead(200, { "Content-Type": "application/json" }); res.end( JSON.stringify({ status: "ok", }), ); } else { res.writeHead(404, { "Content-Type": "text/plain" }); res.end("Not Found"); } }); server?.unref?.(); const stop = () => { return new Promise((resolve, reject) => { server.close((error) => { if (error) reject(error); else resolve(); }); }); }; const start = () => { return new Promise((resolve, reject) => { server.once("error", reject); server.listen(port, hostname, () => { resolve(); console.log( `Healthcheck server running on http://${hostname}:${port}/health`, ); }); // Закрываем сервер при активации AbortController controller.signal.addEventListener("abort", () => { console.log("Healthcheck server shutting down due to abort signal."); stop().then(reject, reject); }); }); }; return { start, stop, }; } export const startHealthServer = ( controller: AbortController, defaultPort: number = 8000, defaultHostName: string = "127.0.0.1", ) => { return createHealthServer(controller, defaultPort, defaultHostName).start(); };