fix(GRO-2652): start server before initAuth; retry auth init on ECONNRESET
Previously: await initAuth() was a top-level ESM await. Any boot-time ECONNRESET from Postgres propagated as an uncaught module-evaluation error and killed the process before the server even started. Now: - serve() starts immediately so /health and public routes are available - initAuth() runs in a retry loop (up to 10 attempts, exponential 500 ms → 30 s); a permanent failure degrades to 503 on auth routes (existing catch-to-503 in authRouter) rather than crashing the pod Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
+22
-2
@@ -292,14 +292,34 @@ api.route("/search", searchRouter);
|
|||||||
api.route("/buffer-rules", bufferRulesRouter);
|
api.route("/buffer-rules", bufferRulesRouter);
|
||||||
api.route("/routes", routesRouter);
|
api.route("/routes", routesRouter);
|
||||||
|
|
||||||
|
// Start the HTTP server first so /health and public routes are available immediately.
|
||||||
|
// Auth initialization runs afterward with retry — a transient DB ECONNRESET at boot
|
||||||
|
// must not crash the process (GRO-2652). Auth routes return 503 until initAuth succeeds.
|
||||||
const port = Number(process.env.PORT ?? 3000);
|
const port = Number(process.env.PORT ?? 3000);
|
||||||
await initAuth();
|
|
||||||
console.log(`API server listening on port ${port}`);
|
|
||||||
const server = serve({ fetch: app.fetch, port });
|
const server = serve({ fetch: app.fetch, port });
|
||||||
|
console.log(`API server listening on port ${port}`);
|
||||||
|
|
||||||
// Start background reminder scheduler (runs every minute to check for upcoming appointments)
|
// Start background reminder scheduler (runs every minute to check for upcoming appointments)
|
||||||
startReminderScheduler();
|
startReminderScheduler();
|
||||||
|
|
||||||
|
let initAttempt = 0;
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
await initAuth();
|
||||||
|
break;
|
||||||
|
} catch (err) {
|
||||||
|
initAttempt++;
|
||||||
|
const delay = Math.min(2 ** initAttempt * 500, 30_000);
|
||||||
|
console.error(`[auth] initAuth attempt ${initAttempt} failed: ${err}`);
|
||||||
|
if (initAttempt >= 10) {
|
||||||
|
console.error("[auth] auth init permanently failed — auth endpoints will serve 503");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
console.error(`[auth] retrying in ${delay}ms`);
|
||||||
|
await new Promise((r) => setTimeout(r, delay));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function shutdown() {
|
function shutdown() {
|
||||||
console.log("Shutting down gracefully...");
|
console.log("Shutting down gracefully...");
|
||||||
// SIGTERM/SIGINT → server.close() → callback → process.exit(0)
|
// SIGTERM/SIGINT → server.close() → callback → process.exit(0)
|
||||||
|
|||||||
Reference in New Issue
Block a user