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
JavaScript
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