UNPKG

defect-inspection-tools-mcp-server

Version:

Defect inspection tools server handling defect detection, analysis, and reporting with AI/ML capabilities for quality control

283 lines 10.2 kB
import { DatabaseService } from './database-service.js'; import { ExternalApiService } from './external-api-service.js'; import { BaseService, ServiceHealthStatus } from './base-service.js'; import { logger } from '../utils/logger.js'; import { config } from '../utils/config.js'; export class ServiceManager { constructor() { this.services = new Map(); this.isInitialized = false; } static getInstance() { if (!ServiceManager.instance) { ServiceManager.instance = new ServiceManager(); } return ServiceManager.instance; } // Initialize all services async initialize() { if (this.isInitialized) { logger.warn('Service manager already initialized'); return; } try { logger.info('Initializing service manager'); // Initialize database service await this.initializeDatabaseService(); // Initialize external API services await this.initializeExternalApiServices(); this.isInitialized = true; logger.info('Service manager initialized successfully', { serviceCount: this.services.size, services: Array.from(this.services.keys()) }); } catch (error) { logger.error('Failed to initialize service manager', { error: error.message }); throw error; } } // Initialize database service async initializeDatabaseService() { const dbConfig = { uri: config.mongoUri, databaseName: config.dbName, timeout: 30000, retries: 3, retryDelay: 1000, maxPoolSize: 10, minPoolSize: 2, maxIdleTimeMS: 30000, serverSelectionTimeoutMS: 5000 }; const dbService = new DatabaseService(dbConfig); await dbService.initialize(); this.services.set('database', dbService); logger.info('Database service initialized'); } // Initialize external API services async initializeExternalApiServices() { // OpenAI service if (config.openaiApiKey) { const openaiService = new ExternalApiService('OpenAI', { baseURL: 'https://api.openai.com/v1', timeout: 60000, retries: 2, retryDelay: 2000, defaultHeaders: { 'Authorization': `Bearer ${config.openaiApiKey}`, 'Content-Type': 'application/json' }, rateLimitPerSecond: 5 }); this.services.set('openai', openaiService); logger.info('OpenAI service initialized'); } // Perplexity service if (config.perplexityApiKey) { const perplexityService = new ExternalApiService('Perplexity', { baseURL: 'https://api.perplexity.ai', timeout: 60000, retries: 2, retryDelay: 2000, defaultHeaders: { 'Authorization': `Bearer ${config.perplexityApiKey}`, 'Content-Type': 'application/json' }, rateLimitPerSecond: 3 }); this.services.set('perplexity', perplexityService); logger.info('Perplexity service initialized'); } // Cohere service if (config.cohereApiKey) { const cohereService = new ExternalApiService('Cohere', { baseURL: 'https://api.cohere.ai/v1', timeout: 60000, retries: 2, retryDelay: 2000, defaultHeaders: { 'Authorization': `Bearer ${config.cohereApiKey}`, 'Content-Type': 'application/json' }, rateLimitPerSecond: 5 }); this.services.set('cohere', cohereService); logger.info('Cohere service initialized'); } // Typesense service if (config.typesenseHost) { const typesenseService = new ExternalApiService('Typesense', { baseURL: `${config.typesenseProtocol}://${config.typesenseHost}:${config.typesensePort}`, timeout: 30000, retries: 3, retryDelay: 1000, defaultHeaders: { 'X-TYPESENSE-API-KEY': config.typesenseApiKey || '', 'Content-Type': 'application/json' }, rateLimitPerSecond: 20 }); this.services.set('typesense', typesenseService); logger.info('Typesense service initialized'); } } // Get a service by name getService(serviceName) { return this.services.get(serviceName); } // Get database service getDatabaseService() { return this.getService('database'); } // Get external API service getExternalApiService(serviceName) { return this.getService(serviceName); } // Get all services getAllServices() { return new Map(this.services); } // Health check for all services async healthCheck() { const serviceHealths = []; let healthyCount = 0; for (const [serviceName, service] of this.services) { try { const status = await service.getHealthStatus(); const metrics = service.getMetrics(); serviceHealths.push({ serviceName, status, metrics, timestamp: new Date() }); if (status === ServiceHealthStatus.HEALTHY) { healthyCount++; } } catch (error) { logger.error(`Health check failed for service ${serviceName}`, { serviceName, error: error.message }); serviceHealths.push({ serviceName, status: ServiceHealthStatus.UNHEALTHY, metrics: {}, timestamp: new Date() }); } } // Determine overall health const totalServices = this.services.size; let overallStatus; if (healthyCount === totalServices) { overallStatus = ServiceHealthStatus.HEALTHY; } else if (healthyCount >= totalServices / 2) { overallStatus = ServiceHealthStatus.DEGRADED; } else { overallStatus = ServiceHealthStatus.UNHEALTHY; } return { status: overallStatus, services: serviceHealths, timestamp: new Date() }; } // Get service metrics async getServiceMetrics() { const metrics = {}; for (const [serviceName, service] of this.services) { try { metrics[serviceName] = service.getMetrics(); } catch (error) { logger.error(`Failed to get metrics for service ${serviceName}`, { serviceName, error: error.message }); metrics[serviceName] = { error: error.message }; } } return metrics; } // Shutdown all services async shutdown() { logger.info('Shutting down service manager'); const shutdownPromises = Array.from(this.services.entries()).map(async ([serviceName, service]) => { try { // Database service has a close method if (service instanceof DatabaseService) { await service.close(); } logger.info(`Service ${serviceName} shut down successfully`); } catch (error) { logger.error(`Error shutting down service ${serviceName}`, { serviceName, error: error.message }); } }); await Promise.all(shutdownPromises); this.services.clear(); this.isInitialized = false; logger.info('Service manager shut down successfully'); } // Check if service manager is initialized isServiceManagerInitialized() { return this.isInitialized; } // Reset all service metrics resetAllMetrics() { for (const [serviceName, service] of this.services) { try { service.resetMetrics(); logger.info(`Metrics reset for service ${serviceName}`); } catch (error) { logger.error(`Failed to reset metrics for service ${serviceName}`, { serviceName, error: error.message }); } } } // Add a custom service addService(serviceName, service) { if (this.services.has(serviceName)) { logger.warn(`Service ${serviceName} already exists, replacing`); } this.services.set(serviceName, service); logger.info(`Service ${serviceName} added to service manager`); } // Remove a service removeService(serviceName) { const removed = this.services.delete(serviceName); if (removed) { logger.info(`Service ${serviceName} removed from service manager`); } else { logger.warn(`Service ${serviceName} not found for removal`); } return removed; } // Get service status summary getServiceStatusSummary() { return Array.from(this.services.entries()).map(([serviceName, service]) => ({ serviceName, status: this.isInitialized ? 'running' : 'not_initialized', config: service.getConfig() })); } } // Export singleton instance export const serviceManager = ServiceManager.getInstance(); // Export service classes for direct use export { DatabaseService, ExternalApiService, BaseService, ServiceHealthStatus }; //# sourceMappingURL=index.js.map