UNPKG

@re-shell/cli

Version:

Full-stack development platform uniting microservices and microfrontends. Build complete applications with .NET (ASP.NET Core Web API, Minimal API), Java (Spring Boot, Quarkus, Micronaut, Vert.x), Rust (Actix-Web, Warp, Rocket, Axum), Python (FastAPI, Dja

399 lines (398 loc) 13.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.gracefulDegradation = exports.GracefulDegradation = void 0; /** * Graceful degradation under resource constraints */ const events_1 = require("events"); class GracefulDegradation extends events_1.EventEmitter { constructor() { super(); this.currentLevel = 0; // 0 = normal operation this.activatedActions = []; this.monitoring = false; this.degradationLevels = [ { name: 'normal', priority: 0, memoryThreshold: 0, cpuThreshold: 0, actions: [] }, { name: 'light_constraints', priority: 1, memoryThreshold: 80, // MB cpuThreshold: 70, // % actions: [ { type: 'disable_feature', target: 'auto_update_check', reversible: true }, { type: 'reduce_quality', target: 'progress_animations', parameters: { fps: 15 }, reversible: true }, { type: 'limit_concurrency', target: 'file_operations', parameters: { maxConcurrent: 3 }, reversible: true } ] }, { name: 'moderate_constraints', priority: 2, memoryThreshold: 120, // MB cpuThreshold: 85, // % actions: [ { type: 'disable_feature', target: 'syntax_highlighting', reversible: true }, { type: 'clear_cache', target: 'template_cache', reversible: false }, { type: 'limit_concurrency', target: 'network_requests', parameters: { maxConcurrent: 2 }, reversible: true }, { type: 'delay_operations', target: 'background_tasks', parameters: { delayMs: 5000 }, reversible: true } ] }, { name: 'severe_constraints', priority: 3, memoryThreshold: 160, // MB cpuThreshold: 95, // % actions: [ { type: 'disable_feature', target: 'file_watching', reversible: true }, { type: 'disable_feature', target: 'plugin_system', reversible: true }, { type: 'clear_cache', target: 'all_caches', reversible: false }, { type: 'limit_concurrency', target: 'all_operations', parameters: { maxConcurrent: 1 }, reversible: true } ] }, { name: 'critical_constraints', priority: 4, memoryThreshold: 200, // MB cpuThreshold: 98, // % actions: [ { type: 'disable_feature', target: 'non_essential_commands', reversible: true }, { type: 'clear_cache', target: 'memory_intensive_caches', reversible: false } ] } ]; } static getInstance() { if (!GracefulDegradation.instance) { GracefulDegradation.instance = new GracefulDegradation(); } return GracefulDegradation.instance; } /** * Start monitoring system constraints */ startMonitoring(intervalMs = 5000) { if (this.monitoring) return; this.monitoring = true; this.monitorInterval = setInterval(() => { this.checkConstraints(); }, intervalMs); // Initial check this.checkConstraints(); this.emit('monitoringStarted', { interval: intervalMs }); } /** * Stop monitoring */ stopMonitoring() { if (!this.monitoring) return; this.monitoring = false; if (this.monitorInterval) { clearInterval(this.monitorInterval); this.monitorInterval = undefined; } // Restore normal operation this.restoreNormalOperation(); this.emit('monitoringStopped'); } /** * Manually trigger degradation to a specific level */ degradeToLevel(level) { if (level < 0 || level >= this.degradationLevels.length) { throw new Error(`Invalid degradation level: ${level}`); } this.applyDegradationLevel(level); } /** * Get current degradation status */ getStatus() { return { level: this.currentLevel, levelName: this.degradationLevels[this.currentLevel].name, activatedActions: [...this.activatedActions], constraints: this.getCurrentConstraints() }; } /** * Check if a feature is currently disabled */ isFeatureDisabled(feature) { return this.activatedActions.some(action => action.type === 'disable_feature' && action.target === feature); } /** * Get current concurrency limit for a target */ getConcurrencyLimit(target) { const action = this.activatedActions.find(action => action.type === 'limit_concurrency' && action.target === target); return action?.parameters?.maxConcurrent || null; } /** * Get current operation delay for a target */ getOperationDelay(target) { const action = this.activatedActions.find(action => action.type === 'delay_operations' && action.target === target); return action?.parameters?.delayMs || 0; } /** * Add custom degradation level */ addDegradationLevel(level) { // Insert in priority order let insertIndex = this.degradationLevels.findIndex(l => l.priority > level.priority); if (insertIndex === -1) { insertIndex = this.degradationLevels.length; } this.degradationLevels.splice(insertIndex, 0, level); this.emit('degradationLevelAdded', level); } /** * Force garbage collection if available */ forceGarbageCollection() { if (global.gc) { global.gc(); this.emit('garbageCollectionForced'); return true; } return false; } /** * Check current system constraints and apply degradation if needed */ checkConstraints() { const constraints = this.getCurrentConstraints(); const requiredLevel = this.calculateRequiredDegradationLevel(constraints); if (requiredLevel !== this.currentLevel) { this.applyDegradationLevel(requiredLevel); } this.emit('constraintsChecked', { constraints, level: this.currentLevel }); } /** * Get current system constraints */ getCurrentConstraints() { const memory = process.memoryUsage(); const memoryMB = memory.heapUsed / 1024 / 1024; // Estimate CPU usage (simplified) const cpuUsage = process.cpuUsage(); const cpuPercent = (cpuUsage.user + cpuUsage.system) / 10000; // Rough estimate return { memory: { current: memoryMB, limit: 500, // Assume 500MB limit available: 500 - memoryMB }, cpu: { current: Math.min(100, cpuPercent), limit: 100 }, operations: { running: 0, // Would be populated by operation managers queued: 0, limit: 10 } }; } /** * Calculate required degradation level based on constraints */ calculateRequiredDegradationLevel(constraints) { let requiredLevel = 0; for (let i = 1; i < this.degradationLevels.length; i++) { const level = this.degradationLevels[i]; if (constraints.memory.current >= level.memoryThreshold || constraints.cpu.current >= level.cpuThreshold) { requiredLevel = i; } } // Add hysteresis to prevent oscillation if (requiredLevel < this.currentLevel) { const currentLevelDef = this.degradationLevels[this.currentLevel]; const hysteresis = 10; // 10% hysteresis if (constraints.memory.current >= (currentLevelDef.memoryThreshold - hysteresis) || constraints.cpu.current >= (currentLevelDef.cpuThreshold - hysteresis)) { requiredLevel = this.currentLevel; // Stay at current level } } return requiredLevel; } /** * Apply degradation actions for a specific level */ applyDegradationLevel(targetLevel) { const previousLevel = this.currentLevel; if (targetLevel > this.currentLevel) { // Increasing degradation - apply new actions for (let level = this.currentLevel + 1; level <= targetLevel; level++) { const levelDef = this.degradationLevels[level]; this.applyActions(levelDef.actions); } } else if (targetLevel < this.currentLevel) { // Decreasing degradation - reverse actions for (let level = this.currentLevel; level > targetLevel; level--) { const levelDef = this.degradationLevels[level]; this.reverseActions(levelDef.actions); } } this.currentLevel = targetLevel; this.emit('degradationLevelChanged', { previousLevel, currentLevel: targetLevel, levelName: this.degradationLevels[targetLevel].name, activatedActions: this.activatedActions.length }); // Force GC at higher degradation levels if (targetLevel >= 2) { this.forceGarbageCollection(); } } /** * Apply degradation actions */ applyActions(actions) { for (const action of actions) { this.applyAction(action); this.activatedActions.push({ ...action }); } } /** * Reverse degradation actions */ reverseActions(actions) { for (const action of actions) { if (action.reversible) { this.reverseAction(action); this.activatedActions = this.activatedActions.filter(a => !(a.type === action.type && a.target === action.target)); } } } /** * Apply a single degradation action */ applyAction(action) { this.emit('actionApplied', action); switch (action.type) { case 'disable_feature': this.emit('featureDisabled', { feature: action.target }); break; case 'reduce_quality': this.emit('qualityReduced', { target: action.target, parameters: action.parameters }); break; case 'limit_concurrency': this.emit('concurrencyLimited', { target: action.target, limit: action.parameters?.maxConcurrent }); break; case 'clear_cache': this.emit('cacheCleared', { target: action.target }); break; case 'delay_operations': this.emit('operationsDelayed', { target: action.target, delay: action.parameters?.delayMs }); break; } } /** * Reverse a single degradation action */ reverseAction(action) { this.emit('actionReversed', action); switch (action.type) { case 'disable_feature': this.emit('featureEnabled', { feature: action.target }); break; case 'reduce_quality': this.emit('qualityRestored', { target: action.target }); break; case 'limit_concurrency': this.emit('concurrencyRestored', { target: action.target }); break; case 'delay_operations': this.emit('operationDelayRemoved', { target: action.target }); break; } } /** * Restore normal operation (level 0) */ restoreNormalOperation() { if (this.currentLevel > 0) { this.applyDegradationLevel(0); } } } exports.GracefulDegradation = GracefulDegradation; // Export singleton instance exports.gracefulDegradation = GracefulDegradation.getInstance();