mirror of
https://github.com/fosrl/pangolin.git
synced 2026-03-25 03:56:38 +00:00
63 lines
2.0 KiB
TypeScript
63 lines
2.0 KiB
TypeScript
import { Pool, PoolConfig } from "pg";
|
|
import logger from "@server/logger";
|
|
|
|
export function createPoolConfig(
|
|
connectionString: string,
|
|
maxConnections: number,
|
|
idleTimeoutMs: number,
|
|
connectionTimeoutMs: number
|
|
): PoolConfig {
|
|
return {
|
|
connectionString,
|
|
max: maxConnections,
|
|
idleTimeoutMillis: idleTimeoutMs,
|
|
connectionTimeoutMillis: connectionTimeoutMs,
|
|
// TCP keepalive to prevent silent connection drops by NAT gateways,
|
|
// load balancers, and other intermediate network devices (e.g. AWS
|
|
// NAT Gateway drops idle TCP connections after ~350s)
|
|
keepAlive: true,
|
|
keepAliveInitialDelayMillis: 10000, // send first keepalive after 10s of idle
|
|
// Allow connections to be released and recreated more aggressively
|
|
// to avoid stale connections building up
|
|
allowExitOnIdle: false
|
|
};
|
|
}
|
|
|
|
export function attachPoolErrorHandlers(pool: Pool, label: string): void {
|
|
pool.on("error", (err) => {
|
|
// This catches errors on idle clients in the pool. Without this
|
|
// handler an unexpected disconnect would crash the process.
|
|
logger.error(
|
|
`Unexpected error on idle ${label} database client: ${err.message}`
|
|
);
|
|
});
|
|
|
|
pool.on("connect", (client) => {
|
|
// Set a statement timeout on every new connection so a single slow
|
|
// query can't block the pool forever
|
|
client.query("SET statement_timeout = '30s'").catch((err: Error) => {
|
|
logger.warn(
|
|
`Failed to set statement_timeout on ${label} client: ${err.message}`
|
|
);
|
|
});
|
|
});
|
|
}
|
|
|
|
export function createPool(
|
|
connectionString: string,
|
|
maxConnections: number,
|
|
idleTimeoutMs: number,
|
|
connectionTimeoutMs: number,
|
|
label: string
|
|
): Pool {
|
|
const pool = new Pool(
|
|
createPoolConfig(
|
|
connectionString,
|
|
maxConnections,
|
|
idleTimeoutMs,
|
|
connectionTimeoutMs
|
|
)
|
|
);
|
|
attachPoolErrorHandlers(pool, label);
|
|
return pool;
|
|
} |