← back to Homesonspec
apps/workers/src/health-server.ts
58 lines
import http from "node:http";
export interface HealthVerdict {
healthy: boolean;
reason: string;
}
/**
* Auxiliary liveness probe for the worker.
*
* CRITICAL (TK-10240 prod incident 2026-08-09): a bind failure here — e.g.
* EADDRINUSE when the chosen port is already taken on the shared Kamatera host,
* which crash-looped the worker on the first prod deploy — must NEVER crash the
* worker. The probe is AUXILIARY; the worker keeps draining the queue. Without a
* `.on('error')` handler the emitted 'error' event is unhandled → uncaughtException
* → process abort → pm2 crash-loop: the exact failure mode this ticket set out to
* eliminate, reintroduced through the probe. So we log and continue instead.
*
* Binds 127.0.0.1 by default so the probe is local-only (pm2 / monitoring on the
* box), never publicly exposed.
*/
export function startHealthServer(opts: {
port: number;
host?: string;
health: () => HealthVerdict;
log?: (...args: unknown[]) => void;
errorLog?: (...args: unknown[]) => void;
}): http.Server {
const host = opts.host ?? "127.0.0.1";
const log = opts.log ?? ((...a: unknown[]) => console.log(...a));
const errorLog = opts.errorLog ?? ((...a: unknown[]) => console.error(...a));
const server = http.createServer((req, res) => {
if (req.url === "/health") {
const verdict = opts.health();
res.writeHead(verdict.healthy ? 200 : 503, { "content-type": "application/json" });
res.end(JSON.stringify(verdict));
return;
}
res.writeHead(404);
res.end();
});
// Non-fatal: a probe that can't bind must not take the worker down with it.
server.on("error", (err) => {
const code = (err as NodeJS.ErrnoException).code ?? String(err);
errorLog(`workers: health endpoint failed to bind ${host}:${opts.port} (${code}); continuing without it`);
});
server.listen(opts.port, host, () => log(`workers: health endpoint on ${host}:${opts.port}/health`));
return server;
}
/** Close a health server only if it actually bound (close() on a non-listening server throws). */
export function closeHealthServer(server: http.Server): void {
if (server.listening) server.close();
}