UNPKG

polyv-live-cli

Version:

CLI tool for managing PolyV live streaming services.

476 lines 19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PerformanceOptimizer = void 0; const events_1 = require("events"); const adaptive_polling_1 = require("./adaptive-polling"); const render_optimizer_1 = require("./render-optimizer"); const memory_manager_1 = require("./memory-manager"); const api_optimizer_1 = require("./api-optimizer"); const batch_request_manager_1 = require("./batch-request-manager"); const api_analytics_1 = require("./api-analytics"); const change_detector_1 = require("./change-detector"); const connection_pool_manager_1 = require("./connection-pool-manager"); const fallback_manager_1 = require("./fallback-manager"); const performance_monitor_1 = require("./performance-monitor"); const error_recovery_manager_1 = require("./error-recovery-manager"); class PerformanceOptimizer extends events_1.EventEmitter { constructor(config = {}) { super(); this.isRunning = false; this.startTime = Date.now(); this.config = { enableAdaptivePolling: true, enableRenderOptimization: true, enableMemoryManagement: true, enableApiOptimization: true, enableBatchRequests: true, enableApiAnalytics: true, enableChangeDetection: true, enableConnectionPooling: true, enableFallbackManagement: true, enablePerformanceMonitoring: true, enableErrorRecovery: true, monitoringInterval: 10000, autoOptimizationThreshold: 70, ...config, }; this.initializeComponents(); this.setupEventHandlers(); } start() { if (this.isRunning) { return; } this.isRunning = true; this.startTime = Date.now(); if (this.config.enableAdaptivePolling && this.adaptivePollingManager) { this.adaptivePollingManager.start(); } if (this.config.enableRenderOptimization && this.renderOptimizer) { this.renderOptimizer.start(); } if (this.config.enableMemoryManagement && this.memoryManager) { this.memoryManager.start(); } if (this.config.enableApiAnalytics && this.apiAnalytics) { this.apiAnalytics.start(); } if (this.config.enableBatchRequests && this.batchRequestManager) { this.batchRequestManager.start(); } if (this.config.enableConnectionPooling && this.connectionPoolManager) { this.connectionPoolManager.start(); } if (this.config.enableFallbackManagement && this.fallbackManager) { this.fallbackManager.start(); } if (this.config.enablePerformanceMonitoring && this.performanceMonitor) { this.performanceMonitor.start(); } if (this.config.enableErrorRecovery && this.errorRecoveryManager) { this.errorRecoveryManager.start(); } this.startPerformanceMonitoring(); this.emit('optimizerStarted', { timestamp: Date.now(), config: this.config, }); } stop() { if (!this.isRunning) { return; } this.isRunning = false; if (this.monitoringTimer) { clearInterval(this.monitoringTimer); this.monitoringTimer = undefined; } if (this.adaptivePollingManager) { this.adaptivePollingManager.stop(); } if (this.renderOptimizer) { this.renderOptimizer.stop(); } if (this.memoryManager) { this.memoryManager.stop(); } if (this.apiAnalytics) { this.apiAnalytics.stop(); } if (this.batchRequestManager) { this.batchRequestManager.stop(); } if (this.connectionPoolManager) { this.connectionPoolManager.stop(); } if (this.fallbackManager) { this.fallbackManager.stop(); } if (this.performanceMonitor) { this.performanceMonitor.stop(); } if (this.errorRecoveryManager) { this.errorRecoveryManager.stop(); } const finalMetrics = this.getPerformanceMetrics(); const uptime = Date.now() - this.startTime; this.emit('optimizerStopped', { timestamp: Date.now(), uptime, finalMetrics, }); } getPerformanceMetrics() { const components = {}; if (this.adaptivePollingManager) { components.adaptivePolling = this.adaptivePollingManager.getStats(); } if (this.renderOptimizer) { components.renderOptimizer = this.renderOptimizer.getMetrics(); } if (this.memoryManager) { components.memoryManager = this.memoryManager.getStats(); } if (this.apiOptimizer) { components.apiOptimizer = this.apiOptimizer.getStats(); } if (this.batchRequestManager) { components.batchRequests = this.batchRequestManager.getStats(); } if (this.apiAnalytics) { components.apiAnalytics = this.apiAnalytics.getPerformanceMetrics(); } if (this.changeDetector) { components.changeDetection = this.changeDetector.getStatistics(); } if (this.connectionPoolManager) { components.connectionPooling = this.connectionPoolManager.getStats(); } if (this.fallbackManager) { components.fallbackManagement = this.fallbackManager.getStats(); } if (this.performanceMonitor) { components.performanceMonitoring = this.performanceMonitor.getMetrics(); } if (this.errorRecoveryManager) { components.errorRecovery = this.errorRecoveryManager.getStatistics(); } const overallScore = this.calculatePerformanceScore(components); const recommendations = this.generateRecommendations(components, overallScore); const systemResources = this.calculateSystemResources(components); const optimizationImpact = this.calculateOptimizationImpact(components); return { overallScore, components, recommendations, systemResources, optimizationImpact, }; } registerComponent(componentId, componentType, options) { if (this.renderOptimizer) { this.renderOptimizer.registerComponent(componentId, componentType, options); } } registerDataSource(dataSourceId, initialInterval) { if (this.adaptivePollingManager) { this.adaptivePollingManager.registerDataSource(dataSourceId, initialInterval); } } async optimizeApiRequest(method, url, params, body, options) { const requestId = `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; const startTime = performance.now(); try { let result; if (this.config.enableBatchRequests && this.batchRequestManager) { result = await this.batchRequestManager.addRequest(method, url, params, body, options); } else if (this.config.enableApiOptimization && this.apiOptimizer) { result = await this.apiOptimizer.optimizeRequest(method, url, params, body, options); } else { result = { method, url, params, body, timestamp: Date.now() }; } const responseTime = performance.now() - startTime; if (this.apiAnalytics) { this.apiAnalytics.recordRequest(requestId, method, url, responseTime, { success: true, requestSize: this.estimateSize(params, body), responseSize: this.estimateSize(result), }); } return result; } catch (error) { const responseTime = performance.now() - startTime; if (this.apiAnalytics) { this.apiAnalytics.recordRequest(requestId, method, url, responseTime, { success: false, error: error instanceof Error ? error.message : 'Unknown error', requestSize: this.estimateSize(params, body), }); } throw error; } } reportDataChange(dataSourceId, changeData) { if (this.adaptivePollingManager) { this.adaptivePollingManager.reportDataChange(dataSourceId, changeData); } if (this.changeDetector) { this.changeDetector.detectChange(dataSourceId, changeData); } } markComponentDirty(componentId, force = false) { if (this.renderOptimizer) { this.renderOptimizer.markDirty(componentId, force); } } registerResource(resource) { if (this.memoryManager) { this.memoryManager.registerResource(resource); } } async forceOptimization() { this.emit('optimizationStarted', { timestamp: Date.now(), }); if (this.memoryManager) { await this.memoryManager.forceCleanup(); } if (this.renderOptimizer) { await this.renderOptimizer.flushRenders(); } if (this.batchRequestManager) { await this.batchRequestManager.flushPendingRequests(); } if (this.apiOptimizer) { this.apiOptimizer.invalidateCache(); } this.emit('optimizationCompleted', { timestamp: Date.now(), metrics: this.getPerformanceMetrics(), }); } updateConfig(newConfig) { this.config = { ...this.config, ...newConfig }; if (newConfig.adaptivePolling && this.adaptivePollingManager) { } if (newConfig.renderOptimizer && this.renderOptimizer) { this.renderOptimizer.updateConfig(newConfig.renderOptimizer); } if (newConfig.memoryManager && this.memoryManager) { this.memoryManager.updateConfig(newConfig.memoryManager); } if (newConfig.apiOptimizer && this.apiOptimizer) { this.apiOptimizer.updateConfig(newConfig.apiOptimizer); } if (newConfig.batchRequests && this.batchRequestManager) { this.batchRequestManager.updateConfig(newConfig.batchRequests); } if (newConfig.apiAnalytics && this.apiAnalytics) { this.apiAnalytics.updateConfig(newConfig.apiAnalytics); } this.emit('configUpdated', { config: this.config, timestamp: Date.now(), }); } getRecommendations() { const metrics = this.getPerformanceMetrics(); return metrics.recommendations; } initializeComponents() { if (this.config.enableAdaptivePolling) { this.adaptivePollingManager = new adaptive_polling_1.AdaptivePollingManager(this.config.adaptivePolling); } if (this.config.enableRenderOptimization) { this.renderOptimizer = new render_optimizer_1.RenderOptimizer(this.config.renderOptimizer); } if (this.config.enableMemoryManagement) { this.memoryManager = new memory_manager_1.MemoryManager(this.config.memoryManager); } if (this.config.enableApiOptimization) { this.apiOptimizer = new api_optimizer_1.ApiOptimizer(this.config.apiOptimizer); } if (this.config.enableBatchRequests) { this.batchRequestManager = new batch_request_manager_1.BatchRequestManager(this.config.batchRequests); } if (this.config.enableApiAnalytics) { this.apiAnalytics = new api_analytics_1.ApiAnalytics(this.config.apiAnalytics); } if (this.config.enableChangeDetection) { this.changeDetector = new change_detector_1.ChangeDetector(this.config.changeDetection); } if (this.config.enableConnectionPooling) { this.connectionPoolManager = new connection_pool_manager_1.ConnectionPoolManager(this.config.connectionPooling); } if (this.config.enableFallbackManagement) { this.fallbackManager = new fallback_manager_1.FallbackManager(this.config.fallbackManagement); } if (this.config.enablePerformanceMonitoring) { this.performanceMonitor = new performance_monitor_1.PerformanceMonitor(this.config.performanceMonitoring); } if (this.config.enableErrorRecovery) { this.errorRecoveryManager = new error_recovery_manager_1.ErrorRecoveryManager(this.config.errorRecovery); } } setupEventHandlers() { if (this.memoryManager) { this.memoryManager.on('criticalMemoryPressure', () => { this.handleCriticalMemoryPressure(); }); } if (this.renderOptimizer) { this.renderOptimizer.on('renderQueueFull', () => { this.handleRenderQueueFull(); }); } if (this.adaptivePollingManager) { this.adaptivePollingManager.on('rateLimitWarning', () => { this.handleRateLimitWarning(); }); } } async handleCriticalMemoryPressure() { this.emit('criticalMemoryPressure', { timestamp: Date.now(), }); await this.forceOptimization(); if (this.renderOptimizer) { this.renderOptimizer.updateConfig({ enableVirtualDom: false, maxPendingRenders: 5, }); } if (this.apiOptimizer) { this.apiOptimizer.updateConfig({ maxCacheSize: 100, cacheTtl: 10000, }); } } handleRenderQueueFull() { this.emit('renderQueueFull', { timestamp: Date.now(), }); if (this.renderOptimizer) { this.renderOptimizer.clearPendingRenders(); } } handleRateLimitWarning() { this.emit('rateLimitWarning', { timestamp: Date.now(), }); if (this.adaptivePollingManager) { } } startPerformanceMonitoring() { this.monitoringTimer = setInterval(() => { if (this.isRunning) { this.performPerformanceCheck(); } }, this.config.monitoringInterval); } performPerformanceCheck() { const metrics = this.getPerformanceMetrics(); this.emit('performanceCheck', { metrics, timestamp: Date.now(), }); if (metrics.overallScore < this.config.autoOptimizationThreshold) { this.emit('autoOptimizationTriggered', { score: metrics.overallScore, threshold: this.config.autoOptimizationThreshold, timestamp: Date.now(), }); this.forceOptimization(); } } calculatePerformanceScore(components) { let totalScore = 0; let componentCount = 0; if (components.renderOptimizer) { const renderScore = Math.min(30, Math.max(0, 30 - (components.renderOptimizer.averageRenderTime / 10))); totalScore += renderScore; componentCount++; } if (components.memoryManager) { const memoryScore = components.memoryManager.pressureLevel === 'normal' ? 25 : components.memoryManager.pressureLevel === 'warning' ? 15 : 5; totalScore += memoryScore; componentCount++; } if (components.apiOptimizer) { const apiScore = Math.min(25, components.apiOptimizer.cacheHitRatio * 25); totalScore += apiScore; componentCount++; } if (components.adaptivePolling) { const pollingScore = Math.min(20, (components.adaptivePolling.dataSourceCount * 4)); totalScore += pollingScore; componentCount++; } return componentCount > 0 ? Math.round(totalScore * (4 / componentCount)) : 0; } generateRecommendations(components, overallScore) { const recommendations = []; if (overallScore < 50) { recommendations.push('Overall performance is poor. Consider immediate optimization.'); } else if (overallScore < 70) { recommendations.push('Performance could be improved. Review recommendations below.'); } if (components.memoryManager) { if (components.memoryManager.pressureLevel === 'critical') { recommendations.push('Critical memory pressure detected. Force cleanup immediately.'); } else if (components.memoryManager.pressureLevel === 'warning') { recommendations.push('Memory usage is high. Consider enabling aggressive cleanup.'); } if (components.memoryManager.leakAlerts > 0) { recommendations.push('Memory leaks detected. Review resource management.'); } } if (components.renderOptimizer) { if (components.renderOptimizer.averageRenderTime > 50) { recommendations.push('Render times are slow. Enable render batching and throttling.'); } if (components.renderOptimizer.skippedRenders > components.renderOptimizer.totalRenders * 0.3) { recommendations.push('Many renders are being skipped. Optimize component updating.'); } } if (components.apiOptimizer && components.apiOptimizer.cacheHitRatio < 0.3) { recommendations.push('Low cache hit ratio. Increase cache TTL or review caching strategy.'); } return recommendations; } calculateSystemResources(components) { const memUsage = process.memoryUsage(); const cpuUsage = process.cpuUsage(); return { cpu: (cpuUsage.user + cpuUsage.system) / 1000000, memory: memUsage.heapUsed / 1024 / 1024, networkRequests: components.apiAnalytics?.requestsPerSecond || 0, renderFrameRate: components.renderOptimizer?.currentFps || 0, }; } calculateOptimizationImpact(components) { return { apiCallsReduced: components.apiOptimizer?.cachedRequests || 0, memoryFreed: components.memoryManager?.cleanupCount || 0, renderTimeImproved: components.renderOptimizer?.skippedRenders || 0, networkBandwidthSaved: components.apiOptimizer?.bytesSaved || 0, }; } estimateSize(...data) { return data.reduce((total, item) => { if (item) { return total + JSON.stringify(item).length; } return total; }, 0); } } exports.PerformanceOptimizer = PerformanceOptimizer; //# sourceMappingURL=performance-optimizer.js.map