diff --git a/backend/src/db/neo4j.ts b/backend/src/db/neo4j.ts index 2002f0386..4ab28a648 100644 --- a/backend/src/db/neo4j.ts +++ b/backend/src/db/neo4j.ts @@ -17,11 +17,25 @@ const defaultOptions = { export function getDriver(options = {}) { const { uri, username, password } = { ...defaultOptions, ...options } if (!driver) { - driver = neo4j.driver(uri, neo4j.auth.basic(username, password)) + driver = neo4j.driver(uri, neo4j.auth.basic(username, password), { + maxConnectionPoolSize: 50, + connectionAcquisitionTimeout: 30000, + }) } return driver } +export async function closeDriver() { + if (driver) { + await driver.close() + driver = undefined as unknown as Driver + } + if (neodeInstance) { + await neodeInstance.close() + neodeInstance = undefined as unknown as Neode + } +} + let neodeInstance: Neode export function getNeode(options = {}) { if (!neodeInstance) { diff --git a/backend/src/index.ts b/backend/src/index.ts index 519e6fc51..08fe47d30 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -1,10 +1,11 @@ import CONFIG from './config' +import { closeDriver } from './db/neo4j' import { loggerPlugin } from './plugins/apolloLogger' import createProxy from './proxy' import createServer from './server' async function main() { - const { httpServer } = await createServer({ + const { server, httpServer } = await createServer({ plugins: [loggerPlugin], }) const url = new URL(CONFIG.GRAPHQL_URI) @@ -31,6 +32,20 @@ async function main() { console.log(`Proxying requests to ${target}`) }) } + + // Graceful shutdown: close Neo4j driver and Apollo server on process signals. + // This prevents connection pool leaks during nodemon restarts in development + // and ensures clean shutdown in production. + const shutdown = async () => { + /* eslint-disable-next-line no-console */ + console.log('Shutting down...') + await server.stop() + httpServer.close() + await closeDriver() + process.exit(0) + } + process.on('SIGTERM', shutdown) + process.on('SIGINT', shutdown) } // eslint-disable-next-line promise/prefer-await-to-callbacks, @typescript-eslint/use-unknown-in-catch-callback-variable