Four separate postgres() clients were open simultaneously (app, timer, snapshots, socket), each defaulting to 10 connections, exhausting the database's max_connections limit. Replaced with a single shared lazy- initialized client in server/db.ts using a Proxy to defer the DATABASE_URL check until first use (preserving test compatibility). Also bumps the CS2 Champions Stage stochastic test from 200 → 1000 iterations to eliminate flakiness. https://claude.ai/code/session_019w21Nkf5TvTZHH6oVHaQXR
29 lines
1.1 KiB
TypeScript
29 lines
1.1 KiB
TypeScript
import { drizzle } from "drizzle-orm/postgres-js";
|
|
import postgres from "postgres";
|
|
import * as schema from "~/database/schema";
|
|
|
|
// Cache the client on globalThis so HMR re-evaluations and multiple server
|
|
// modules share a single connection pool instead of each opening their own.
|
|
declare global {
|
|
// eslint-disable-next-line no-var
|
|
var __pgClient: ReturnType<typeof postgres> | undefined;
|
|
// eslint-disable-next-line no-var
|
|
var __pgDb: ReturnType<typeof drizzle<typeof schema>> | undefined;
|
|
}
|
|
|
|
function getDb() {
|
|
if (!globalThis.__pgDb) {
|
|
if (!process.env.DATABASE_URL) throw new Error("DATABASE_URL is required");
|
|
globalThis.__pgClient ??= postgres(process.env.DATABASE_URL);
|
|
globalThis.__pgDb = drizzle(globalThis.__pgClient, { schema });
|
|
}
|
|
return globalThis.__pgDb;
|
|
}
|
|
|
|
// Export a Proxy so callers can use `db.query.foo` etc. without calling getDb() themselves.
|
|
// The proxy defers the DATABASE_URL check until the first actual property access.
|
|
export const db = new Proxy({} as ReturnType<typeof drizzle<typeof schema>>, {
|
|
get(_target, prop) {
|
|
return getDb()[prop as keyof ReturnType<typeof drizzle<typeof schema>>];
|
|
},
|
|
});
|