fix: keep decision center health probe fast
This commit is contained in:
@@ -71,6 +71,8 @@ const serviceStartedAt = new Date().toISOString();
|
|||||||
const recentLogs: JsonRecord[] = [];
|
const recentLogs: JsonRecord[] = [];
|
||||||
let schemaReady = false;
|
let schemaReady = false;
|
||||||
let schemaLastError: JsonRecord | null = null;
|
let schemaLastError: JsonRecord | null = null;
|
||||||
|
let databaseHealth: JsonRecord = { ok: false, recordCount: 0, checkedAt: "", error: null };
|
||||||
|
let databaseHealthRefreshInFlight = false;
|
||||||
|
|
||||||
function envString(name: string, fallback: string): string {
|
function envString(name: string, fallback: string): string {
|
||||||
const value = process.env[name];
|
const value = process.env[name];
|
||||||
@@ -292,6 +294,29 @@ async function waitForSchema(): Promise<void> {
|
|||||||
throw new Error(`Decision Center schema initialization failed: ${JSON.stringify(schemaLastError)}`);
|
throw new Error(`Decision Center schema initialization failed: ${JSON.stringify(schemaLastError)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function refreshDatabaseHealth(): Promise<void> {
|
||||||
|
if (databaseHealthRefreshInFlight) return;
|
||||||
|
databaseHealthRefreshInFlight = true;
|
||||||
|
try {
|
||||||
|
const rows = await sql<{ count: string | number }[]>`SELECT count(*) AS count FROM decision_center_records`;
|
||||||
|
databaseHealth = {
|
||||||
|
ok: true,
|
||||||
|
recordCount: Number(rows[0]?.count ?? 0),
|
||||||
|
checkedAt: new Date().toISOString(),
|
||||||
|
error: null,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
databaseHealth = {
|
||||||
|
ok: false,
|
||||||
|
recordCount: 0,
|
||||||
|
checkedAt: new Date().toISOString(),
|
||||||
|
error: errorToJson(error),
|
||||||
|
};
|
||||||
|
} finally {
|
||||||
|
databaseHealthRefreshInFlight = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function deployInfo(): JsonRecord {
|
function deployInfo(): JsonRecord {
|
||||||
return {
|
return {
|
||||||
serviceId: envString("UNIDESK_DEPLOY_SERVICE_ID", "decision-center"),
|
serviceId: envString("UNIDESK_DEPLOY_SERVICE_ID", "decision-center"),
|
||||||
@@ -301,17 +326,8 @@ function deployInfo(): JsonRecord {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function health(): Promise<JsonRecord> {
|
function health(): JsonRecord {
|
||||||
let dbOk = false;
|
const dbOk = databaseHealth.ok === true;
|
||||||
let recordCount = 0;
|
|
||||||
let dbError: JsonValue = null;
|
|
||||||
try {
|
|
||||||
const rows = await sql<{ count: string | number }[]>`SELECT count(*) AS count FROM decision_center_records`;
|
|
||||||
dbOk = true;
|
|
||||||
recordCount = Number(rows[0]?.count ?? 0);
|
|
||||||
} catch (error) {
|
|
||||||
dbError = errorToJson(error);
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
ok: schemaReady && dbOk,
|
ok: schemaReady && dbOk,
|
||||||
service: "decision-center",
|
service: "decision-center",
|
||||||
@@ -319,8 +335,8 @@ async function health(): Promise<JsonRecord> {
|
|||||||
startedAt: serviceStartedAt,
|
startedAt: serviceStartedAt,
|
||||||
storage: "postgres",
|
storage: "postgres",
|
||||||
schemaReady,
|
schemaReady,
|
||||||
recordCount,
|
recordCount: Number(databaseHealth.recordCount ?? 0),
|
||||||
database: { ok: dbOk, error: dbError },
|
database: databaseHealth,
|
||||||
deploy: deployInfo(),
|
deploy: deployInfo(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -473,7 +489,7 @@ async function route(req: Request): Promise<Response> {
|
|||||||
return jsonResponse({ ok: true, service: "decision-center", status: "alive", startedAt: serviceStartedAt, deploy: deployInfo() });
|
return jsonResponse({ ok: true, service: "decision-center", status: "alive", startedAt: serviceStartedAt, deploy: deployInfo() });
|
||||||
}
|
}
|
||||||
if (url.pathname === "/health") {
|
if (url.pathname === "/health") {
|
||||||
const body = await health();
|
const body = health();
|
||||||
return jsonResponse(body, body.ok === true ? 200 : 503);
|
return jsonResponse(body, body.ok === true ? 200 : 503);
|
||||||
}
|
}
|
||||||
if (url.pathname === "/logs" && method === "GET") return jsonResponse({ ok: true, logs: recentLogs.slice(-200) });
|
if (url.pathname === "/logs" && method === "GET") return jsonResponse({ ok: true, logs: recentLogs.slice(-200) });
|
||||||
@@ -504,7 +520,12 @@ Bun.serve({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
void waitForSchema().catch((error) => {
|
void waitForSchema()
|
||||||
log("error", "schema_init_failed", { error: errorToJson(error) });
|
.then(() => refreshDatabaseHealth())
|
||||||
});
|
.catch((error) => {
|
||||||
|
log("error", "schema_init_failed", { error: errorToJson(error) });
|
||||||
|
});
|
||||||
|
setInterval(() => {
|
||||||
|
if (schemaReady) void refreshDatabaseHealth();
|
||||||
|
}, 15_000).unref();
|
||||||
log("info", "service_started", { host: config.host, port: config.port, storage: "postgres" });
|
log("info", "service_started", { host: config.host, port: config.port, storage: "postgres" });
|
||||||
|
|||||||
Reference in New Issue
Block a user