From cea2f6bffcce577f0a4d5fa146f9f9424a092da4 Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Fri, 6 Mar 2026 10:49:05 +0000 Subject: [PATCH] fix(pg-cache): allow cache to reopen after close for process survival The PgPoolCacheManager.close() permanently set closed=true with no way to reopen. If the process received SIGTERM but didn't exit (e.g. during provisioning or restart under load), all subsequent getPgPool() calls threw 'Cannot add to cache after it has been closed'. Changes: - Reset closed=false after disposal completes in PgPoolCacheManager.close() - Reset closePromise in module-level close() via finally block (matching the pattern already used in graphile-cache.ts) This allows the cache to accept new entries if the process survives the shutdown signal. --- postgres/pg-cache/src/lru.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/postgres/pg-cache/src/lru.ts b/postgres/pg-cache/src/lru.ts index 119fb37af..b0c61c1ed 100644 --- a/postgres/pg-cache/src/lru.ts +++ b/postgres/pg-cache/src/lru.ts @@ -105,6 +105,9 @@ export class PgPoolCacheManager { this.closed = true; this.clear(); await this.waitForDisposals(); + // Re-open the cache so it can accept new entries if the process + // survives the shutdown signal (e.g. during provisioning or restart). + this.closed = false; } async waitForDisposals(): Promise { @@ -141,9 +144,14 @@ export const close = async (verbose = false): Promise => { if (closePromise.promise) return closePromise.promise; closePromise.promise = (async () => { - if (verbose) log.info('Closing pg cache...'); - await pgCache.close(); - if (verbose) log.success('PG cache disposed.'); + try { + if (verbose) log.info('Closing pg cache...'); + await pgCache.close(); + if (verbose) log.success('PG cache disposed.'); + } finally { + // Reset so close() can be called again if the process survives. + closePromise.promise = null; + } })(); return closePromise.promise; @@ -158,4 +166,4 @@ SYS_EVENTS.forEach(event => { export const teardownPgPools = async (verbose = false): Promise => { return close(verbose); -}; \ No newline at end of file +};