UNPKG

syia-mcp-utils

Version:

Global utility functions for MCP server

243 lines (242 loc) 9.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.initializeConnections = initializeConnections; exports.getMongoClient = getMongoClient; exports.getDevApiClient = getDevApiClient; exports.getEtlDevClient = getEtlDevClient; exports.getEtlDevDataClient = getEtlDevDataClient; exports.getEtlDevDataDbName = getEtlDevDataDbName; exports.getDevApiDbName = getDevApiDbName; exports.getEtlDevDbName = getEtlDevDbName; exports.getConnectionStatus = getConnectionStatus; exports.closeConnections = closeConnections; const mongodb_1 = require("mongodb"); const logger_js_1 = require("./logger.js"); const config_1 = require("./config"); // MongoDB connection options for better resilience const mongoOptions = { serverApi: { version: mongodb_1.ServerApiVersion.v1, strict: true, deprecationErrors: true, }, maxPoolSize: 10, minPoolSize: 5, maxIdleTimeMS: 60000, connectTimeoutMS: 30000, socketTimeoutMS: 45000, retryWrites: true, retryReads: true, }; // Main MongoDB clients let client = null; let secondaryClient = null; // Specific database clients let devApiClient = null; let etlDevClient = null; let etlDevDataClient = null; // Connection status tracking const connectionStatus = { primary: false, secondary: false, devApi: false, etlDev: false, etlDevData: false, }; /** * Connect to MongoDB with retry logic * @param uri MongoDB connection URI * @param name Connection name for logging * @returns MongoDB client instance */ async function connectWithRetry(uri, name) { const maxRetries = 5; const retryDelayMs = 2000; for (let attempt = 1; attempt <= maxRetries; attempt++) { try { const client = new mongodb_1.MongoClient(uri, mongoOptions); await client.connect(); // Verify connection by pinging the database await client.db().command({ ping: 1 }); logger_js_1.logger.info(`Connected to ${name} MongoDB instance (attempt ${attempt})`); return client; } catch (error) { logger_js_1.logger.error(`Failed to connect to ${name} MongoDB (attempt ${attempt}/${maxRetries}):`, error); if (attempt === maxRetries) { logger_js_1.logger.error(`Max retries reached for ${name} MongoDB connection`); return null; } // Wait before retrying logger_js_1.logger.info(`Retrying ${name} MongoDB connection in ${retryDelayMs}ms...`); await new Promise(resolve => setTimeout(resolve, retryDelayMs)); } } return null; } /** * Initialize all MongoDB connections * This should be called during server startup */ async function initializeConnections() { // Skip MongoDB connection in test environment if (process.env.NODE_ENV === 'test') { logger_js_1.logger.info('Test environment detected, skipping MongoDB connections'); return; } try { // Initialize primary connection if (!client && (0, config_1.getConfig)().mongoUri) { client = await connectWithRetry((0, config_1.getConfig)().mongoUri, 'primary'); connectionStatus.primary = client !== null; } // Initialize secondary connection if configured if (!secondaryClient && (0, config_1.getConfig)().secondaryMongoUri) { secondaryClient = await connectWithRetry((0, config_1.getConfig)().secondaryMongoUri, 'secondary'); connectionStatus.secondary = secondaryClient !== null; } // Initialize dev-api connection if (!devApiClient && (0, config_1.getConfig)().devApiMongoUri) { devApiClient = await connectWithRetry((0, config_1.getConfig)().devApiMongoUri, 'dev-syia-api'); connectionStatus.devApi = devApiClient !== null; } // Initialize etl-dev connection if (!etlDevClient && (0, config_1.getConfig)().etlDevMongoUri) { etlDevClient = await connectWithRetry((0, config_1.getConfig)().etlDevMongoUri, 'syia-etl-dev'); connectionStatus.etlDev = etlDevClient !== null; } // Initialize etl-dev-data connection if (!etlDevDataClient && (0, config_1.getConfig)().etlDevDataUri) { etlDevDataClient = await connectWithRetry((0, config_1.getConfig)().etlDevDataUri, 'syia-etl-dev-data'); connectionStatus.etlDevData = etlDevDataClient !== null; } // Check if primary connection is established if (!connectionStatus.primary) { throw new Error('Failed to establish primary MongoDB connection'); } logger_js_1.logger.info('MongoDB connections initialized', { connectionStatus }); } catch (error) { logger_js_1.logger.error('Error initializing MongoDB connections:', error); throw error; } } /** * Get MongoDB client based on URI or default */ async function getMongoClient(uri) { // Skip MongoDB connection in test environment if (process.env.NODE_ENV === 'test') { logger_js_1.logger.info('Test environment detected, skipping MongoDB connection'); return {}; } // If URI is provided, use it for a specific connection if (uri) { // Check for dev-api connection if (uri === (0, config_1.getConfig)().devApiMongoUri) { if (!devApiClient) { // If not initialized during startup, initialize now devApiClient = await connectWithRetry(uri, 'dev-syia-api'); connectionStatus.devApi = devApiClient !== null; } return devApiClient || {}; } // Check for etl-dev connection if (uri === (0, config_1.getConfig)().etlDevMongoUri) { if (!etlDevClient) { // If not initialized during startup, initialize now etlDevClient = await connectWithRetry(uri, 'syia-etl-dev'); connectionStatus.etlDev = etlDevClient !== null; } return etlDevClient || {}; } // Check for etl-dev-data connection if (uri === (0, config_1.getConfig)().etlDevDataUri) { if (!etlDevDataClient) { // If not initialized during startup, initialize now etlDevDataClient = await connectWithRetry(uri, 'syia-etl-dev-data'); connectionStatus.etlDevData = etlDevDataClient !== null; } return etlDevDataClient || {}; } // Check for secondary connection if (uri === (0, config_1.getConfig)().secondaryMongoUri) { if (!secondaryClient) { // If not initialized during startup, initialize now secondaryClient = await connectWithRetry(uri, 'secondary'); connectionStatus.secondary = secondaryClient !== null; } return secondaryClient || {}; } // For custom URI, create a new connection logger_js_1.logger.info('Creating new MongoDB connection for custom URI'); const customClient = await connectWithRetry(uri, 'custom'); return customClient || {}; } // Use primary connection by default if (!client) { // If not initialized during startup, initialize now client = await connectWithRetry((0, config_1.getConfig)().mongoUri, 'primary'); connectionStatus.primary = client !== null; } return client || {}; } // Remaining helper functions for specific clients async function getDevApiClient() { return getMongoClient((0, config_1.getConfig)().devApiMongoUri); } async function getEtlDevClient() { return getMongoClient((0, config_1.getConfig)().etlDevMongoUri); } async function getEtlDevDataClient() { return getMongoClient((0, config_1.getConfig)().etlDevDataUri); } function getEtlDevDataDbName() { return (0, config_1.getConfig)().etlDevDataDbName; } function getDevApiDbName() { return (0, config_1.getConfig)().devApiDbName; } function getEtlDevDbName() { return (0, config_1.getConfig)().etlDevDbName; } /** * Get connection status for monitoring */ function getConnectionStatus() { return { ...connectionStatus }; } /** * Close all MongoDB connections */ async function closeConnections() { logger_js_1.logger.info('Closing MongoDB connections...'); const closePromises = []; if (client) { closePromises.push(client.close().catch(err => { logger_js_1.logger.error('Error closing primary MongoDB connection:', err); })); } if (secondaryClient) { closePromises.push(secondaryClient.close().catch(err => { logger_js_1.logger.error('Error closing secondary MongoDB connection:', err); })); } if (devApiClient) { closePromises.push(devApiClient.close().catch(err => { logger_js_1.logger.error('Error closing dev-api MongoDB connection:', err); })); } if (etlDevClient) { closePromises.push(etlDevClient.close().catch(err => { logger_js_1.logger.error('Error closing etl-dev MongoDB connection:', err); })); } if (etlDevDataClient) { closePromises.push(etlDevDataClient.close().catch(err => { logger_js_1.logger.error('Error closing etl-dev-data MongoDB connection:', err); })); } await Promise.all(closePromises); logger_js_1.logger.info('All MongoDB connections closed'); }