@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
JavaScript
"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();