repositories / will
will
owned by admin
src/agent/readiness.ts
Rawimport { createServer, type Server } from 'node:http'
import { sendJson } from '../shared/http.ts'
/**
* Pod-local readiness endpoint for the deployment platform (spec AC4):
* readiness is local initialization only; external outages mark degraded
* state, never readiness false.
*/
export interface ReadinessChecks {
sessionReady: boolean
serviceReachable: boolean
telegramLoopReady: boolean
storageOk: boolean
configValid: boolean
degraded?: string[]
}
export interface ReadinessServer {
server: Server
setReady(checks: ReadinessChecks): void
close(): Promise<void>
}
export function isReady(checks: ReadinessChecks): boolean {
return checks.sessionReady && checks.serviceReachable && checks.configValid
}
export function startReadinessServer(addr: string): Promise<ReadinessServer> {
let current: ReadinessChecks = {
sessionReady: false,
serviceReachable: false,
telegramLoopReady: false,
storageOk: true,
configValid: true,
}
const server = createServer((req, res) => {
const url = new URL(req.url ?? '/', 'http://localhost')
if (url.pathname === '/readyz' || url.pathname === '/healthz') {
sendJson(res, isReady(current) ? 200 : 503, { ready: isReady(current), checks: current })
return
}
sendJson(res, 404, { error: 'not found' })
})
return new Promise((resolve, reject) => {
const [host, port] = addr.split(':')
server.once('error', reject)
server.listen(Number(port), host, () => {
resolve({
server,
setReady(checks) {
current = checks
},
close: () => new Promise<void>((res) => server.close(() => res())),
})
})
})
}