import { type Knex } from "knex"; import knex from "knex"; export function createKnexInstance(config: Knex.Config): Knex { if (config.connection && typeof config.connection === "object") { const conn = config.connection as Record; if (conn.keepAlive === undefined) { conn.keepAlive = true; conn.keepAliveInitialDelayMillis = conn.keepAliveInitialDelayMillis ?? 10000; } } config.pool = { maxConnectionLifetimeMillis: 1800000, maxConnectionLifetimeJitterMillis: 300000, ...config.pool, propagateCreateError: false, idleTimeoutMillis: 10000, reapIntervalMillis: 1000, acquireTimeoutMillis: 30000, createTimeoutMillis: 30000, validate: (connection: unknown) => { if (typeof connection !== "object" || connection === null) return false; const conn = connection as Record; if (conn._ending === true || conn._closed === true) return false; return true; }, afterCreate: (( conn: Knex.Client & Record, done: (err: Error | null, conn: Knex.Client) => void, ) => { // pg driver: 소켓 레벨 keepAlive 설정 const stream = (conn as Record).connection as | { stream?: { setKeepAlive?: (enable: boolean, initialDelay: number) => void } } | undefined; if (stream?.stream?.setKeepAlive) { stream.stream.setKeepAlive(true, 10000); } done(null, conn); }) satisfies Knex.PoolConfig["afterCreate"], }; return knex(config); }