Skip to main content
Glama
by Coder-RL
service-mesh-orchestrator.ts20.2 kB
import { EventEmitter } from 'events'; import { createLogger } from '../../shared/src/logging.js'; import ServiceMesh from './service-mesh.js'; import APIGateway from './api-gateway.js'; import { memoryOptimizationSuite } from '../../shared/src/memory-optimization-suite.js'; export interface OrchestrationConfig { environment: 'development' | 'staging' | 'production'; region: string; zone: string; gateway: { enabled: boolean; port: number; host: string; cors: { enabled: boolean; origins: string[]; methods: string[]; headers: string[]; }; ssl: { enabled: boolean; certPath?: string; keyPath?: string; }; }; serviceMesh: { enabled: boolean; discovery: { enabled: boolean; interval: number; timeout: number; }; loadBalancing: { strategy: 'round_robin' | 'least_connections' | 'weighted_round_robin'; healthCheckInterval: number; }; circuitBreaker: { enabled: boolean; failureThreshold: number; recoveryTimeout: number; }; tracing: { enabled: boolean; samplingRate: number; exportEndpoint?: string; }; }; monitoring: { enabled: boolean; metricsInterval: number; alerting: { enabled: boolean; endpoints: string[]; }; }; security: { authentication: { enabled: boolean; providers: string[]; defaultScheme: 'bearer' | 'basic' | 'apikey'; }; authorization: { enabled: boolean; defaultPolicy: 'allow' | 'deny'; }; rateLimit: { enabled: boolean; global: { requestsPerSecond: number; burstSize: number; }; }; }; } export interface ServiceConfiguration { name: string; version: string; replicas: number; resources: { cpu: number; memory: number; disk: number; }; environment: Record<string, string>; healthCheck: { path: string; port: number; initialDelay: number; interval: number; timeout: number; retries: number; }; deployment: { strategy: 'rolling' | 'blue_green' | 'canary'; maxUnavailable: number; maxSurge: number; }; } export interface DeploymentStatus { serviceId: string; status: 'pending' | 'deploying' | 'running' | 'failed' | 'stopped'; replicas: { desired: number; current: number; ready: number; updated: number; }; conditions: DeploymentCondition[]; startTime: number; lastUpdateTime: number; } export interface DeploymentCondition { type: 'Available' | 'Progressing' | 'ReplicaFailure'; status: 'True' | 'False' | 'Unknown'; reason: string; message: string; lastTransitionTime: number; } export interface ServiceMeshStatus { healthy: boolean; totalServices: number; healthyServices: number; totalRequests: number; errorRate: number; averageLatency: number; circuitBreakerTrips: number; lastUpdate: number; } export class ServiceMeshOrchestrator extends EventEmitter { private logger = createLogger('ServiceMeshOrchestrator'); private config: OrchestrationConfig; private serviceMesh: ServiceMesh; private apiGateway: APIGateway; private deployments = new Map<string, DeploymentStatus>(); private serviceConfigs = new Map<string, ServiceConfiguration>(); private monitoringInterval: NodeJS.Timeout | null = null; private healthCheckInterval: NodeJS.Timeout | null = null; constructor(config: Partial<OrchestrationConfig> = {}) { super(); this.config = this.mergeDefaultConfig(config); this.serviceMesh = new ServiceMesh(); this.apiGateway = new APIGateway(this.serviceMesh); this.setupEventHandlers(); this.initializeRoutes(); if (this.config.monitoring.enabled) { this.startMonitoring(); } this.logger.info('Service Mesh Orchestrator initialized', { environment: this.config.environment, region: this.config.region, gateway: this.config.gateway.enabled, monitoring: this.config.monitoring.enabled }); } private mergeDefaultConfig(config: Partial<OrchestrationConfig>): OrchestrationConfig { return { environment: 'development', region: 'default', zone: 'default', gateway: { enabled: true, port: 3000, host: '0.0.0.0', cors: { enabled: true, origins: ['*'], methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], headers: ['Content-Type', 'Authorization', 'X-API-Key'] }, ssl: { enabled: false } }, serviceMesh: { enabled: true, discovery: { enabled: true, interval: 30000, timeout: 5000 }, loadBalancing: { strategy: 'round_robin', healthCheckInterval: 30000 }, circuitBreaker: { enabled: true, failureThreshold: 5, recoveryTimeout: 60000 }, tracing: { enabled: false, samplingRate: 0.1 } }, monitoring: { enabled: true, metricsInterval: 30000, alerting: { enabled: false, endpoints: [] } }, security: { authentication: { enabled: false, providers: [], defaultScheme: 'bearer' }, authorization: { enabled: false, defaultPolicy: 'allow' }, rateLimit: { enabled: true, global: { requestsPerSecond: 100, burstSize: 200 } } }, ...config }; } private setupEventHandlers(): void { // Service Mesh events this.serviceMesh.on('serviceRegistered', (service) => { this.logger.info(`Service registered in mesh: ${service.name}`, { id: service.id }); this.updateDeploymentStatus(service.name, 'running'); }); this.serviceMesh.on('serviceDeregistered', (service) => { this.logger.info(`Service deregistered from mesh: ${service.name}`, { id: service.id }); this.updateDeploymentStatus(service.name, 'stopped'); }); this.serviceMesh.on('serviceHealthChanged', (service, health) => { this.logger.info(`Service health changed: ${service.name} -> ${health}`, { id: service.id }); this.handleServiceHealthChange(service, health); }); this.serviceMesh.on('circuitBreakerTripped', (serviceId) => { this.logger.warn(`Circuit breaker tripped: ${serviceId}`); this.handleCircuitBreakerTrip(serviceId); }); // API Gateway events this.apiGateway.on('routeRegistered', (route) => { this.logger.info(`API route registered: ${route.method} ${route.path} -> ${route.serviceName}`); }); // Memory optimization events memoryOptimizationSuite.on('memoryLeakDetected', (leak) => { this.logger.error(`Memory leak detected in service mesh:`, leak); this.handleMemoryLeak(leak); }); } private initializeRoutes(): void { // Register core API routes this.apiGateway.registerRoute('/health', 'GET', 'orchestrator', { timeout: 5000, retries: 1, middleware: ['logging', 'validation'] }); this.apiGateway.registerRoute('/metrics', 'GET', 'orchestrator', { timeout: 10000, retries: 1, middleware: ['logging', 'validation', 'authentication'] }); this.apiGateway.registerRoute('/services', 'GET', 'orchestrator', { timeout: 10000, retries: 1, middleware: ['logging', 'validation', 'authentication'] }); // Register service-specific routes dynamically this.registerServiceRoutes(); } private registerServiceRoutes(): void { // Register routes for known services const knownServices = [ 'ai-integration', 'visualization-insights', 'memory-optimization', 'attention-mechanisms', 'transformer-architecture', 'language-model' ]; for (const serviceName of knownServices) { // Health check route this.apiGateway.registerRoute(`/${serviceName}/health`, 'GET', serviceName, { timeout: 5000, retries: 2, middleware: ['logging', 'validation'] }); // API routes this.apiGateway.registerRoute(`/${serviceName}/*`, 'POST', serviceName, { timeout: 30000, retries: 3, authentication: { required: this.config.security.authentication.enabled, schemes: [this.config.security.authentication.defaultScheme], providers: this.config.security.authentication.providers }, rateLimit: this.config.security.rateLimit.enabled ? this.config.security.rateLimit.global : undefined, middleware: ['logging', 'validation', 'authentication', 'authorization', 'rateLimit'] }); } } async deployService( config: ServiceConfiguration, options: { waitForReady?: boolean; timeout?: number; } = {} ): Promise<string> { const deploymentId = `${config.name}_${config.version}_${Date.now()}`; const { waitForReady = true, timeout = 300000 } = options; // 5 minutes default this.logger.info(`Starting deployment: ${config.name}:${config.version}`, { deploymentId }); // Create deployment status const deployment: DeploymentStatus = { serviceId: deploymentId, status: 'deploying', replicas: { desired: config.replicas, current: 0, ready: 0, updated: 0 }, conditions: [{ type: 'Progressing', status: 'True', reason: 'DeploymentStarted', message: 'Deployment has started', lastTransitionTime: Date.now() }], startTime: Date.now(), lastUpdateTime: Date.now() }; this.deployments.set(deploymentId, deployment); this.serviceConfigs.set(deploymentId, config); try { // Simulate deployment process await this.performDeployment(deploymentId, config); deployment.status = 'running'; deployment.conditions.push({ type: 'Available', status: 'True', reason: 'DeploymentAvailable', message: 'Deployment is available', lastTransitionTime: Date.now() }); if (waitForReady) { await this.waitForDeploymentReady(deploymentId, timeout); } this.logger.info(`Deployment completed: ${config.name}:${config.version}`, { deploymentId }); this.emit('deploymentCompleted', { deploymentId, config }); return deploymentId; } catch (error) { deployment.status = 'failed'; deployment.conditions.push({ type: 'ReplicaFailure', status: 'True', reason: 'DeploymentFailed', message: error instanceof Error ? error.message : 'Unknown deployment error', lastTransitionTime: Date.now() }); this.logger.error(`Deployment failed: ${config.name}:${config.version}`, error); this.emit('deploymentFailed', { deploymentId, config, error }); throw error; } } private async performDeployment(deploymentId: string, config: ServiceConfiguration): Promise<void> { // Simulate deployment steps const deployment = this.deployments.get(deploymentId)!; // Register service with mesh const endpoints = [{ host: 'localhost', port: 8000 + Math.floor(Math.random() * 1000), path: '/', protocol: 'http', weight: 1, tags: [config.name, config.version] }]; const serviceId = await this.serviceMesh.registerService( config.name, config.version, endpoints, { protocol: 'http', healthcheck: { enabled: true, path: config.healthCheck.path, interval: config.healthCheck.interval, timeout: config.healthCheck.timeout, healthyThreshold: 2, unhealthyThreshold: config.healthCheck.retries }, metadata: { region: this.config.region, zone: this.config.zone, environment: this.config.environment, capabilities: [], resources: config.resources, dependencies: [], tags: { version: config.version, deployment: deploymentId } } } ); // Update deployment status deployment.replicas.current = config.replicas; deployment.replicas.ready = config.replicas; deployment.replicas.updated = config.replicas; deployment.lastUpdateTime = Date.now(); // Simulate startup time await new Promise(resolve => setTimeout(resolve, 2000)); } private async waitForDeploymentReady(deploymentId: string, timeout: number): Promise<void> { const startTime = Date.now(); while (Date.now() - startTime < timeout) { const deployment = this.deployments.get(deploymentId); if (deployment && deployment.status === 'running' && deployment.replicas.ready >= deployment.replicas.desired) { return; } await new Promise(resolve => setTimeout(resolve, 1000)); } throw new Error(`Deployment readiness timeout: ${deploymentId}`); } async scaleService(deploymentId: string, replicas: number): Promise<void> { const deployment = this.deployments.get(deploymentId); const config = this.serviceConfigs.get(deploymentId); if (!deployment || !config) { throw new Error(`Deployment not found: ${deploymentId}`); } this.logger.info(`Scaling service: ${config.name} from ${deployment.replicas.desired} to ${replicas}`); deployment.replicas.desired = replicas; deployment.lastUpdateTime = Date.now(); deployment.conditions.push({ type: 'Progressing', status: 'True', reason: 'ScalingInProgress', message: `Scaling from ${deployment.replicas.current} to ${replicas} replicas`, lastTransitionTime: Date.now() }); // Simulate scaling await new Promise(resolve => setTimeout(resolve, 1000)); deployment.replicas.current = replicas; deployment.replicas.ready = replicas; deployment.replicas.updated = replicas; this.emit('serviceScaled', { deploymentId, oldReplicas: config.replicas, newReplicas: replicas }); } async stopService(deploymentId: string): Promise<void> { const deployment = this.deployments.get(deploymentId); const config = this.serviceConfigs.get(deploymentId); if (!deployment || !config) { throw new Error(`Deployment not found: ${deploymentId}`); } this.logger.info(`Stopping service: ${config.name}:${config.version}`, { deploymentId }); // Deregister from service mesh const services = this.serviceMesh.getServicesByName(config.name); for (const service of services) { if (service.metadata.tags.deployment === deploymentId) { await this.serviceMesh.deregisterService(service.id); } } deployment.status = 'stopped'; deployment.replicas.current = 0; deployment.replicas.ready = 0; deployment.lastUpdateTime = Date.now(); this.emit('serviceStopped', { deploymentId, config }); } private updateDeploymentStatus(serviceName: string, status: DeploymentStatus['status']): void { for (const [deploymentId, deployment] of this.deployments) { const config = this.serviceConfigs.get(deploymentId); if (config && config.name === serviceName) { deployment.status = status; deployment.lastUpdateTime = Date.now(); } } } private handleServiceHealthChange(service: any, health: string): void { // Find associated deployment for (const [deploymentId, deployment] of this.deployments) { if (service.metadata?.tags?.deployment === deploymentId) { const condition: DeploymentCondition = { type: 'Available', status: health === 'healthy' ? 'True' : 'False', reason: health === 'healthy' ? 'ServiceHealthy' : 'ServiceUnhealthy', message: `Service health is ${health}`, lastTransitionTime: Date.now() }; deployment.conditions.push(condition); deployment.lastUpdateTime = Date.now(); break; } } } private handleCircuitBreakerTrip(serviceId: string): void { // Implement circuit breaker response (e.g., auto-scaling, alerting) this.emit('circuitBreakerTripped', { serviceId, timestamp: Date.now() }); } private handleMemoryLeak(leak: any): void { // Implement memory leak response if (leak.confidence > 0.8) { this.logger.warn(`High-confidence memory leak detected, considering service restart`); this.emit('memoryLeakAlert', leak); } } private startMonitoring(): void { this.monitoringInterval = setInterval(() => { this.collectMetrics(); }, this.config.monitoring.metricsInterval); this.healthCheckInterval = setInterval(() => { this.performHealthChecks(); }, this.config.serviceMesh.loadBalancing.healthCheckInterval); } private collectMetrics(): void { const meshMetrics = this.serviceMesh.getMetrics(); const gatewayMetrics = this.apiGateway.getMetrics(); const services = this.serviceMesh.getServices(); const status: ServiceMeshStatus = { healthy: meshMetrics.errorRate < 0.1, totalServices: services.length, healthyServices: services.filter(s => s.status === 'healthy').length, totalRequests: gatewayMetrics.totalRequests, errorRate: gatewayMetrics.failedRequests / Math.max(gatewayMetrics.totalRequests, 1), averageLatency: gatewayMetrics.averageLatency, circuitBreakerTrips: meshMetrics.circuitBreakerTrips, lastUpdate: Date.now() }; this.emit('metricsCollected', { mesh: meshMetrics, gateway: gatewayMetrics, status }); } private performHealthChecks(): void { // Health checks are handled by the service mesh // This could be extended to perform additional checks const unhealthyServices = this.serviceMesh.getServices().filter(s => s.status === 'unhealthy'); if (unhealthyServices.length > 0) { this.logger.warn(`Found ${unhealthyServices.length} unhealthy services`); this.emit('unhealthyServicesDetected', unhealthyServices); } } // Public API methods getServiceMesh(): ServiceMesh { return this.serviceMesh; } getAPIGateway(): APIGateway { return this.apiGateway; } getConfiguration(): OrchestrationConfig { return { ...this.config }; } getDeployments(): DeploymentStatus[] { return Array.from(this.deployments.values()); } getDeployment(deploymentId: string): DeploymentStatus | null { return this.deployments.get(deploymentId) || null; } getServiceConfiguration(deploymentId: string): ServiceConfiguration | null { return this.serviceConfigs.get(deploymentId) || null; } getServiceMeshStatus(): ServiceMeshStatus { const meshMetrics = this.serviceMesh.getMetrics(); const services = this.serviceMesh.getServices(); return { healthy: meshMetrics.errorRate < 0.1, totalServices: services.length, healthyServices: services.filter(s => s.status === 'healthy').length, totalRequests: meshMetrics.totalRequests, errorRate: meshMetrics.errorRate, averageLatency: meshMetrics.averageLatency, circuitBreakerTrips: meshMetrics.circuitBreakerTrips, lastUpdate: Date.now() }; } async handleAPIRequest(request: any): Promise<any> { return await this.apiGateway.handleRequest(request); } async shutdown(): Promise<void> { this.logger.info('Shutting down Service Mesh Orchestrator'); if (this.monitoringInterval) { clearInterval(this.monitoringInterval); } if (this.healthCheckInterval) { clearInterval(this.healthCheckInterval); } // Stop all deployments for (const deploymentId of this.deployments.keys()) { try { await this.stopService(deploymentId); } catch (error) { this.logger.error(`Error stopping service ${deploymentId}:`, error); } } await this.serviceMesh.shutdown(); this.logger.info('Service Mesh Orchestrator shutdown completed'); } } export default ServiceMeshOrchestrator;

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Coder-RL/Claude_MCPServer_Dev1'

If you have feedback or need assistance with the MCP directory API, please join our Discord server