UNPKG

@intuitionrobotics/thunderstorm

Version:
57 lines 2.62 kB
import {} from "express"; import { handler } from "../../../../modules/server/handler.js"; import {} from "../../../../../shared/types.js"; import { Storm } from "../../../../core/Storm.js"; import { currentTimeMillies } from "@intuitionrobotics/ts-common"; import { isHealthCheckContributor } from "../../../../../shared/health.js"; const statusRank = { pass: 0, warn: 1, fail: 2 }; const worse = (a, b) => (statusRank[a] >= statusRank[b] ? a : b); // Smart, transparent health endpoint — the raw-Express `handler(fn)` form. // // TRANSPARENT — the framework never injects this for you. Mount it explicitly // from your routes file (one visible line), choosing your own path: // // import {healthHandler} from "@intuitionrobotics/thunderstorm/backend"; // v1.get("/health", healthHandler()); // or // v1.get("/health", healthHandler({version})); // // SMART — it enumerates every loaded Storm module and reports env / node / // uptime. Any module implementing HealthCheckContributor (getHealth()) // contributes real subsystem health; the overall status is the worst of them, // and a "fail" is reflected as HTTP 503 so load balancers / uptime probes can // gate on it. export const healthHandler = (opts = {}) => handler(async (_req, res) => { const storm = Storm?.getInstance(); const modules = storm ? storm.filterModules(() => true) : []; const moduleHealth = await Promise.all(modules.map(async (module) => { const name = module.getName(); if (!isHealthCheckContributor(module)) return { name, status: "pass" }; try { const contribution = await module.getHealth(); return { name, status: contribution.status, detail: contribution.detail }; } catch (e) { return { name, status: "fail", detail: e?.message ?? "getHealth() threw" }; } })); const status = moduleHealth.reduce((worst, m) => worse(worst, m.status), "pass"); const report = { status, env: storm?.getEnvironment() ?? "unknown", node: process.version, uptimeSec: Math.floor(process.uptime()), timestamp: currentTimeMillies(), modules: moduleHealth, version: opts.version }; // A failing health check must surface as 503 (probes gate on it); writing // res directly makes handler()'s autoSend a no-op. Otherwise return the // report and autoSend emits 200. if (status === "fail") { res.status(503).json(report); return; } return report; }, { printResponse: false }); //# sourceMappingURL=get.js.map