fix(cloud-api): keep health live nonblocking (#1808)

Route /health/live through cached runtime summary so DB durable retry cannot block liveness probes. Keep /health as the full durable readiness endpoint.\n\nRefs #1807.
This commit is contained in:
Lyon
2026-06-21 10:28:02 +08:00
committed by GitHub
parent a0c54934b2
commit 6cafd495de
+51 -4
View File
@@ -262,20 +262,24 @@ function ensurePreinstalledHwpodSpec({ workspace }) {
export async function buildHealthPayload(options = {}) {
const serviceId = CLOUD_API_SERVICE_ID;
const env = options.env ?? process.env;
const healthMode = options.healthMode === "live" ? "live" : "readiness";
const liveProbe = healthMode === "live";
ensureCodeAgentRuntimeBase(env);
const metadata = buildMetadataFromEnv(env, {
serviceId,
fallbackImageRepository: "ghcr.io/pikastech/hwlab-cloud-api"
});
const dbProbe = await buildDbRuntimeReadiness(env, options.dbProbe);
const runtimeStore = options.runtimeStore ?? createConfiguredCloudRuntimeStore({ ...options, env });
const dbProbe = await buildDbRuntimeReadiness(env, liveProbe ? { ...(options.dbProbe ?? {}), probe: false } : options.dbProbe);
const codeAgent = await describeCodeAgentAvailability(env, options);
const runtime = await runtimeReadiness(options.runtimeStore ?? createConfiguredCloudRuntimeStore({ ...options, env }));
const runtime = liveProbe ? runtimeReadinessSnapshot(runtimeStore) : await runtimeReadiness(runtimeStore);
const db = applyRuntimeDbReadinessLayers(dbProbe, runtime);
const readiness = buildCloudApiReadiness({ db, codeAgent, runtime });
return {
serviceId,
environment: runtimeEnvironment(env),
healthMode,
status: readiness.status,
ready: readiness.ready,
revision: metadata.revision,
@@ -300,11 +304,54 @@ export async function buildHealthPayload(options = {}) {
};
}
function runtimeReadinessSnapshot(runtimeStore) {
if (runtimeStore && typeof runtimeStore.summary === "function") {
try {
const summary = runtimeStore.summary();
return {
...summary,
readinessFresh: false,
readinessSource: "cached-summary"
};
} catch (error) {
return {
adapter: "unknown",
durable: false,
ready: false,
status: "degraded",
blocker: "runtime_readiness_snapshot_failed",
reason: error instanceof Error ? error.message : "Runtime readiness snapshot failed",
readinessFresh: false,
readinessSource: "cached-summary",
valuesRedacted: true,
endpointRedacted: true
};
}
}
return {
adapter: "unknown",
durable: false,
ready: false,
status: "degraded",
blocker: "runtime_readiness_snapshot_unavailable",
reason: "Runtime store does not expose a cached summary for /health/live",
readinessFresh: false,
readinessSource: "cached-summary",
valuesRedacted: true,
endpointRedacted: true
};
}
async function routeRequest(request, response, options) {
const url = new URL(request.url || "/", "http://hwlab-cloud-api.local");
if (request.method === "GET" && (url.pathname === "/health" || url.pathname === "/health/live")) {
sendJson(response, 200, await buildHealthPayload(options));
if (request.method === "GET" && url.pathname === "/health/live") {
sendJson(response, 200, await buildHealthPayload({ ...options, healthMode: "live" }));
return;
}
if (request.method === "GET" && url.pathname === "/health") {
sendJson(response, 200, await buildHealthPayload({ ...options, healthMode: "readiness" }));
return;
}