MongoDB Connection System: Architecture and Implementation#
The backend MongoDB connection system is implemented in backend/src/config/database.ts and uses Mongoose for connection management. It provides robust connection handling, retry logic, connection state tracking, graceful shutdown, health check integration, and test utilities for database management.
Architecture Overview#
The connection system is structured around a set of exported functions and internal state:
connectDatabase: Establishes the MongoDB connection with retry logic.disconnectDatabase: Gracefully closes the connection.isMongoConnected: Reports the current connection state.dropDatabase: Utility for dropping the database in test environments.- Internal state variables (
isConnected,handlersSetup) track connection status and event handler registration.
Integration points exist in backend/src/index.ts (startup and shutdown orchestration) and backend/src/routes/health.ts (health check endpoints).
Retry Logic#
The connectDatabase function implements retry logic for establishing a MongoDB connection. By default, it attempts to connect up to 5 times with a 5-second delay between attempts. Each attempt logs the (masked) MongoDB URI and the attempt number. If all retries fail, it throws an error. The retry parameters are configurable via function arguments.
Example usage:
await connectDatabase(); // uses defaults
await connectDatabase(3, 1000); // 3 retries, 1s delay
Connection State Tracking#
Connection state is tracked using a boolean isConnected and Mongoose's connection.readyState. The system sets up event handlers for Mongoose connection events:
- On
'connected', logs success. - On
'error', logs the error. - On
'disconnected', setsisConnectedtofalse. - On
'reconnected', setsisConnectedtotrue.
Handlers are registered only once per process using a handlersSetup flag to avoid duplicate listeners. The isMongoConnected function returns true only if both isConnected is true and mongoose.connection.readyState is 'connected' (state 1).
Graceful Shutdown Procedures#
Graceful shutdown is coordinated in backend/src/index.ts. On receiving a shutdown signal (SIGINT or SIGTERM), the server:
- Closes the HTTP server.
- Closes queues and disconnects Redis.
- Calls
disconnectDatabaseto close the MongoDB connection.
disconnectDatabase closes the Mongoose connection and sets isConnected to false, logging the event. If the connection is already closed, it does nothing.
Health Check Integration#
Health check endpoints are implemented in backend/src/routes/health.ts:
/health: Returns overall system health, including MongoDB connection status andreadyState. Always returns HTTP 200./health/ready: Returns readiness status. Returns HTTP 200 if ready, 503 if not. MongoDB readiness is determined byisMongoConnected./health/live: Simple liveness check (always HTTP 200).
Health endpoints use isMongoConnected and mongoose.connection.readyState to report MongoDB status.
Test Utilities: Database Dropping#
The dropDatabase utility is intended for test environments only. It throws an error if called in production or when not connected. When invoked, it calls mongoose.connection.dropDatabase() and logs a warning. This ensures test isolation by resetting the database state between tests.
Example usage in tests:
await connectDatabase();
await dropDatabase();
Extending the Connection Management System#
To extend the MongoDB connection system:
- Add new event handlers in
setupConnectionHandlersfor additional Mongoose events as needed. - Adjust connection options in
getConnectionOptionsto tune pooling, timeouts, or direct connection settings. - Integrate additional health checks by updating the health endpoints in
backend/src/routes/health.ts. - For new environments, update environment detection logic in the configuration and connection options.
Troubleshooting Connection Management#
If you encounter connection issues:
- Check logs for connection errors, retry attempts, and event handler outputs.
- Verify retry parameters and environment variables (e.g.,
MONGODB_URI). - Use the
/healthand/health/readyendpoints to inspect current connection status and readiness. - Ensure that
isMongoConnected()returnstrueandmongoose.connection.readyStateis1(connected). - In test environments, ensure
dropDatabaseis not called in production and that the connection is established before dropping.
Unit tests in backend/tests/unit/database.test.ts cover connection, retry logic, state tracking, graceful shutdown, and database dropping behaviors, providing further reference for expected outcomes.
For implementation details, see the main connection logic in backend/src/config/database.ts.