From 34530f4f5dfb2196cd07998c5b090bf8b8b534ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tao=20Bojl=C3=A9n?= Date: Thu, 25 Jun 2026 00:23:57 +0100 Subject: [PATCH] fix: close express-session store on api shutdown (#825) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit connect-pg-simple keeps a recurring pruneSessions timer that calls pool.query on its pool. makeApiServer created the store with the shared KyselyPgPool but never closed it, so the timer kept running after shutdown. In tests this leaked a setInterval per makeMockedServer() call that fired pool.query on the harness's already-closed pinned connection after each test, logging "Failed to prune sessions: Client was closed and is not queryable" indefinitely and hanging the test worker — the loop that forced the manual cancellation of CI run 27951870325. Hold a reference to the store instance and call its close() in the shutdown path. ownsPg is false (we pass in our own pool), so close() only stops the prune timer and won't end the shared pool. Co-authored-by: Claude Opus 4.8 --- server/api.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/api.ts b/server/api.ts index b425ccd..0d3ac0b 100644 --- a/server/api.ts +++ b/server/api.ts @@ -128,10 +128,11 @@ export default async function makeApiServer(deps: Dependencies) { /** * Passport & User Session Configuration */ + const sessionStoreInstance = new sessionStore({ pool: KyselyPgPool }); app.use( session({ secret: process.env.SESSION_SECRET!, - store: new sessionStore({ pool: KyselyPgPool }), + store: sessionStoreInstance, cookie: { secure: process.env.NODE_ENV === 'production', httpOnly: true, @@ -419,6 +420,7 @@ export default async function makeApiServer(deps: Dependencies) { await Promise.all([ apolloServer.stop(), deps.closeSharedResourcesForShutdown(), + sessionStoreInstance.close(), ]); }, }; -- 2.51.2