polyv-live-cli
Version:
CLI tool for managing PolyV live streaming services.
476 lines • 19 kB
JavaScript
"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