mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix: add shutdown timeout and improve health endpoint
- Add 8s shutdown timeout to prevent indefinite hang when app.close() stalls. Stays under Docker's default 10s stop_grace_period. - Health endpoint now checks database connectivity, returns 503 when DB is unreachable so Docker marks container unhealthy. - Removed variant field from health response (single image now).
This commit is contained in:
+24
-5
@@ -108,12 +108,23 @@ await teamsRoutes(app);
|
|||||||
// API docs (Scalar)
|
// API docs (Scalar)
|
||||||
await docsRoutes(app);
|
await docsRoutes(app);
|
||||||
|
|
||||||
// Public health check (minimal - no internal details)
|
// Public health check (checks core dependencies)
|
||||||
app.get("/api/v1/health", async () => ({
|
app.get("/api/v1/health", async (_request, reply) => {
|
||||||
status: "healthy",
|
let dbOk = false;
|
||||||
|
try {
|
||||||
|
db.select().from(schema.settings).limit(1).all();
|
||||||
|
dbOk = true;
|
||||||
|
} catch {
|
||||||
|
/* db unreachable */
|
||||||
|
}
|
||||||
|
|
||||||
|
const status = dbOk ? "healthy" : "unhealthy";
|
||||||
|
const code = dbOk ? 200 : 503;
|
||||||
|
return reply.code(code).send({
|
||||||
|
status,
|
||||||
version: APP_VERSION,
|
version: APP_VERSION,
|
||||||
variant: process.env.STIRLING_VARIANT === "lite" ? "lite" : "full",
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
// Admin health check (full diagnostics)
|
// Admin health check (full diagnostics)
|
||||||
app.get("/api/v1/admin/health", async (request, reply) => {
|
app.get("/api/v1/admin/health", async (request, reply) => {
|
||||||
@@ -161,12 +172,19 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Graceful shutdown
|
// Graceful shutdown
|
||||||
|
const SHUTDOWN_TIMEOUT_MS = 8000;
|
||||||
let shuttingDown = false;
|
let shuttingDown = false;
|
||||||
async function shutdown(signal: string) {
|
async function shutdown(signal: string) {
|
||||||
if (shuttingDown) return;
|
if (shuttingDown) return;
|
||||||
shuttingDown = true;
|
shuttingDown = true;
|
||||||
console.log(`\n${signal} received, shutting down gracefully...`);
|
console.log(`\n${signal} received, shutting down gracefully...`);
|
||||||
|
|
||||||
|
const forceExit = setTimeout(() => {
|
||||||
|
console.error("Shutdown timed out, forcing exit");
|
||||||
|
process.exit(1);
|
||||||
|
}, SHUTDOWN_TIMEOUT_MS);
|
||||||
|
forceExit.unref();
|
||||||
|
|
||||||
cleanupCron.stop();
|
cleanupCron.stop();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -199,6 +217,7 @@ async function shutdown(signal: string) {
|
|||||||
console.error("Error closing database:", err);
|
console.error("Error closing database:", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearTimeout(forceExit);
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user