# MongoDB Handler A singleton MongoDB handler with context manager support for MongoDB collections and automatic retry capabilities. ## Features - **Singleton Pattern**: Ensures only one instance of the MongoDB handler exists - **Context Manager**: Automatically manages connection lifecycle - **Retry Capability**: Automatically retries MongoDB operations on failure - **Connection Pooling**: Configurable connection pooling - **Graceful Degradation**: Handles connection failures without crashing ## Usage ```python from Controllers.Mongo.database import mongo_handler # Use the context manager to access a collection with mongo_handler.collection("users") as users_collection: # Perform operations on the collection users_collection.insert_one({"username": "john", "email": "john@example.com"}) user = users_collection.find_one({"username": "john"}) # Connection is automatically closed when exiting the context ``` ## Configuration MongoDB connection settings are configured via environment variables with the `MONGO_` prefix: - `MONGO_ENGINE`: Database engine (e.g., "mongodb") - `MONGO_USER`: MongoDB username - `MONGO_PASSWORD`: MongoDB password - `MONGO_HOST`: MongoDB host - `MONGO_PORT`: MongoDB port - `MONGO_DB`: Database name - `MONGO_AUTH_DB`: Authentication database ## Monitoring Connection Closure To verify that MongoDB sessions are properly closed, you can implement one of the following approaches: ### 1. Add Logging to the `__exit__` Method ```python def __exit__(self, exc_type, exc_val, exc_tb): """ Exit context, closing the connection. """ if self.client: print(f"Closing MongoDB connection for collection: {self.collection_name}") # Or use a proper logger # logger.info(f"Closing MongoDB connection for collection: {self.collection_name}") self.client.close() self.client = None self.collection = None print(f"MongoDB connection closed successfully") ``` ### 2. Add Connection Tracking ```python class MongoDBHandler: # Add these to your class _open_connections = 0 def get_connection_stats(self): """Return statistics about open connections""" return {"open_connections": self._open_connections} ``` Then modify the `CollectionContext` class: ```python def __enter__(self): try: # Create a new client connection self.client = MongoClient(self.db_handler.uri, **self.db_handler.client_options) # Increment connection counter self.db_handler._open_connections += 1 # Rest of your code... def __exit__(self, exc_type, exc_val, exc_tb): if self.client: # Decrement connection counter self.db_handler._open_connections -= 1 self.client.close() self.client = None self.collection = None ``` ### 3. Use MongoDB's Built-in Monitoring ```python from pymongo import monitoring class ConnectionCommandListener(monitoring.CommandListener): def started(self, event): print(f"Command {event.command_name} started on server {event.connection_id}") def succeeded(self, event): print(f"Command {event.command_name} succeeded in {event.duration_micros} microseconds") def failed(self, event): print(f"Command {event.command_name} failed in {event.duration_micros} microseconds") # Register the listener monitoring.register(ConnectionCommandListener()) ``` ### 4. Add a Test Function ```python def test_connection_closure(): """Test that MongoDB connections are properly closed.""" print("\nTesting connection closure...") # Record initial connection count (if you implemented the counter) initial_count = mongo_handler.get_connection_stats()["open_connections"] # Use multiple nested contexts for i in range(5): with mongo_handler.collection("test_collection") as collection: # Do some simple operation collection.find_one({}) # Check final connection count final_count = mongo_handler.get_connection_stats()["open_connections"] if final_count == initial_count: print("Test passed: All connections were properly closed") return True else: print(f"Test failed: {final_count - initial_count} connections remain open") return False ``` ### 5. Use MongoDB Server Logs You can also check the MongoDB server logs to see connection events: ```bash # Run this on your MongoDB server tail -f /var/log/mongodb/mongod.log | grep "connection" ``` ## Best Practices 1. Always use the context manager pattern to ensure connections are properly closed 2. Keep operations within the context manager as concise as possible 3. Handle exceptions within the context to prevent unexpected behavior 4. Avoid nesting multiple context managers unnecessarily 5. Use the retry decorator for operations that might fail due to transient issues ## LXC Container Configuration ### Authentication Issues If you encounter authentication errors when connecting to the MongoDB container at 10.10.2.13:27017, you may need to update the container configuration: 1. **Check MongoDB Authentication**: Ensure the MongoDB container is configured with the correct authentication mechanism 2. **Verify Network Configuration**: Make sure the container network allows connections from your application 3. **Update MongoDB Configuration**: - Edit the MongoDB configuration file in the container - Ensure `bindIp` is set correctly (e.g., `0.0.0.0` to allow connections from any IP) - Check that authentication is enabled with the correct mechanism 4. **User Permissions**: - Verify that the application user (`appuser`) exists in the MongoDB instance - Ensure the user has the correct roles and permissions for the database ### Example MongoDB Container Configuration ```yaml # Example docker-compose.yml configuration services: mongodb: image: mongo:latest container_name: mongodb environment: - MONGO_INITDB_ROOT_USERNAME=admin - MONGO_INITDB_ROOT_PASSWORD=password volumes: - ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro ports: - "27017:27017" command: mongod --auth ``` ```javascript // Example init-mongo.js db.createUser({ user: 'appuser', pwd: 'apppassword', roles: [ { role: 'readWrite', db: 'appdb' } ] }); ``` ## Troubleshooting ### Common Issues 1. **Authentication Failed**: - Verify username and password in environment variables - Check that the user exists in the specified authentication database - Ensure the user has appropriate permissions 2. **Connection Refused**: - Verify the MongoDB host and port are correct - Check network connectivity between application and MongoDB container - Ensure MongoDB is running and accepting connections 3. **Resource Leaks**: - Use the context manager pattern to ensure connections are properly closed - Monitor connection pool size and active connections - Implement proper error handling to close connections in case of exceptions