@sailboat-computer/resilience
Version:
Enhanced resilience patterns for sailboat computer v3 with marine-specific adaptations
1,050 lines (913 loc) • 27.8 kB
text/typescript
/**
* Graceful degradation strategies with marine-specific adaptations
*/
import {
MarineEnvironmentStatus,
ResilienceEvent,
ResilienceResult
} from '../types';
import {
OperationalContext
} from '../types/marine-constants';
/**
* Service quality level
*/
export enum ServiceQualityLevel {
/**
* Full functionality with optimal performance
*/
OPTIMAL = 'optimal',
/**
* Full functionality with reduced performance
*/
REDUCED = 'reduced',
/**
* Core functionality only
*/
MINIMAL = 'minimal',
/**
* Critical functionality only
*/
CRITICAL = 'critical',
/**
* Emergency functionality only
*/
EMERGENCY = 'emergency'
}
/**
* Feature priority for degradation decisions
*/
export enum FeaturePriority {
/**
* Critical for vessel safety
*/
CRITICAL = 'critical',
/**
* Essential for operation
*/
ESSENTIAL = 'essential',
/**
* Important but can be degraded
*/
IMPORTANT = 'important',
/**
* Useful but non-essential
*/
USEFUL = 'useful',
/**
* Comfort or convenience only
*/
COMFORT = 'comfort'
}
/**
* Degradation strategy configuration
*/
export interface DegradationConfig {
/**
* Default service quality level
*/
defaultQualityLevel: ServiceQualityLevel;
/**
* Whether to adapt to marine conditions
*/
adaptToMarineConditions: boolean;
/**
* Whether to adapt to power status
*/
powerAware: boolean;
/**
* Whether to adapt to connectivity quality
*/
connectivityAware: boolean;
/**
* Quality level thresholds for different conditions
*/
qualityThresholds: {
/**
* Sea state thresholds
*/
seaState: {
rough: ServiceQualityLevel;
veryRough: ServiceQualityLevel;
};
/**
* Power status thresholds
*/
powerStatus: {
conservation: ServiceQualityLevel;
critical: ServiceQualityLevel;
};
/**
* Connectivity quality thresholds (0-1)
*/
connectivityQuality: {
low: number;
lowQualityLevel: ServiceQualityLevel;
veryLow: number;
veryLowQualityLevel: ServiceQualityLevel;
};
};
/**
* Feature toggles configuration
*/
featureToggles: {
/**
* Whether to enable automatic feature toggling
*/
autoToggleFeatures: boolean;
/**
* Minimum priority level for each quality level
*/
qualityLevelMinPriority: {
[ServiceQualityLevel.OPTIMAL]: FeaturePriority;
[ServiceQualityLevel.REDUCED]: FeaturePriority;
[ServiceQualityLevel.MINIMAL]: FeaturePriority;
[ServiceQualityLevel.CRITICAL]: FeaturePriority;
[ServiceQualityLevel.EMERGENCY]: FeaturePriority;
};
};
/**
* Resource limits for different quality levels
*/
resourceLimits: {
/**
* CPU usage percentage (0-100)
*/
cpu: {
[ServiceQualityLevel.OPTIMAL]: number;
[ServiceQualityLevel.REDUCED]: number;
[ServiceQualityLevel.MINIMAL]: number;
[ServiceQualityLevel.CRITICAL]: number;
[ServiceQualityLevel.EMERGENCY]: number;
};
/**
* Memory usage percentage (0-100)
*/
memory: {
[ServiceQualityLevel.OPTIMAL]: number;
[ServiceQualityLevel.REDUCED]: number;
[ServiceQualityLevel.MINIMAL]: number;
[ServiceQualityLevel.CRITICAL]: number;
[ServiceQualityLevel.EMERGENCY]: number;
};
/**
* Network bandwidth usage (KB/s)
*/
bandwidth: {
[ServiceQualityLevel.OPTIMAL]: number;
[ServiceQualityLevel.REDUCED]: number;
[ServiceQualityLevel.MINIMAL]: number;
[ServiceQualityLevel.CRITICAL]: number;
[ServiceQualityLevel.EMERGENCY]: number;
};
/**
* Storage I/O operations per second
*/
storageIops: {
[ServiceQualityLevel.OPTIMAL]: number;
[ServiceQualityLevel.REDUCED]: number;
[ServiceQualityLevel.MINIMAL]: number;
[ServiceQualityLevel.CRITICAL]: number;
[ServiceQualityLevel.EMERGENCY]: number;
};
};
}
/**
* Feature toggle definition
*/
export interface FeatureToggle {
/**
* Feature ID
*/
id: string;
/**
* Feature name
*/
name: string;
/**
* Feature description
*/
description: string;
/**
* Feature priority
*/
priority: FeaturePriority;
/**
* Whether the feature is currently enabled
*/
enabled: boolean;
/**
* Whether the feature can be manually toggled
*/
manualToggleAllowed: boolean;
/**
* Power consumption in watts when enabled
*/
powerConsumption: number;
/**
* CPU usage percentage when enabled
*/
cpuUsage: number;
/**
* Memory usage in MB when enabled
*/
memoryUsage: number;
/**
* Network bandwidth usage in KB/s when enabled
*/
bandwidthUsage: number;
/**
* Storage I/O operations per second when enabled
*/
storageIops: number;
/**
* Marine-specific settings
*/
marineSettings: {
/**
* Whether this feature is required in rough seas
*/
requiredInRoughSeas: boolean;
/**
* Whether this feature is required for navigation
*/
requiredForNavigation: boolean;
/**
* Whether this feature is required for safety
*/
requiredForSafety: boolean;
/**
* Whether this feature requires good connectivity
*/
requiresGoodConnectivity: boolean;
};
}
/**
* Degradation metrics
*/
export interface DegradationMetrics {
/**
* Current service quality level
*/
currentQualityLevel: ServiceQualityLevel;
/**
* Previous service quality level
*/
previousQualityLevel: ServiceQualityLevel;
/**
* Time spent at each quality level (ms)
*/
timeAtQualityLevel: {
[key in ServiceQualityLevel]: number;
};
/**
* Number of quality level changes
*/
qualityLevelChanges: number;
/**
* Feature toggle metrics
*/
featureToggles: {
/**
* Total number of features
*/
total: number;
/**
* Number of enabled features
*/
enabled: number;
/**
* Number of disabled features
*/
disabled: number;
/**
* Number of features toggled automatically
*/
autoToggled: number;
/**
* Number of features toggled manually
*/
manuallyToggled: number;
};
/**
* Resource usage metrics
*/
resourceUsage: {
/**
* CPU usage percentage
*/
cpu: number;
/**
* Memory usage percentage
*/
memory: number;
/**
* Network bandwidth usage (KB/s)
*/
bandwidth: number;
/**
* Storage I/O operations per second
*/
storageIops: number;
/**
* Power consumption in watts
*/
power: number;
};
/**
* Marine-specific metrics
*/
marineMetrics: {
/**
* Time spent in rough seas (ms)
*/
timeInRoughSeas: number;
/**
* Time spent in power conservation mode (ms)
*/
timeInPowerConservation: number;
/**
* Time spent with poor connectivity (ms)
*/
timeWithPoorConnectivity: number;
/**
* Time spent in emergency mode (ms)
*/
timeInEmergencyMode: number;
};
}
/**
* Degradation manager for graceful service degradation
*/
export class DegradationManager {
private config: DegradationConfig;
private currentQualityLevel: ServiceQualityLevel;
private featureToggles: Map<string, FeatureToggle> = new Map();
private metrics: DegradationMetrics;
private eventListeners: ((event: ResilienceEvent) => void)[] = [];
private marineEnvironment?: MarineEnvironmentStatus;
private qualityLevelTimestamps: Map<ServiceQualityLevel, number> = new Map();
private lastQualityUpdateTime: number = Date.now();
constructor(config?: Partial<DegradationConfig>) {
this.config = {
defaultQualityLevel: ServiceQualityLevel.OPTIMAL,
adaptToMarineConditions: true,
powerAware: true,
connectivityAware: true,
qualityThresholds: {
seaState: {
rough: ServiceQualityLevel.REDUCED,
veryRough: ServiceQualityLevel.MINIMAL
},
powerStatus: {
conservation: ServiceQualityLevel.REDUCED,
critical: ServiceQualityLevel.CRITICAL
},
connectivityQuality: {
low: 0.3,
lowQualityLevel: ServiceQualityLevel.REDUCED,
veryLow: 0.1,
veryLowQualityLevel: ServiceQualityLevel.MINIMAL
}
},
featureToggles: {
autoToggleFeatures: true,
qualityLevelMinPriority: {
[ServiceQualityLevel.OPTIMAL]: FeaturePriority.COMFORT,
[ServiceQualityLevel.REDUCED]: FeaturePriority.USEFUL,
[ServiceQualityLevel.MINIMAL]: FeaturePriority.IMPORTANT,
[ServiceQualityLevel.CRITICAL]: FeaturePriority.ESSENTIAL,
[ServiceQualityLevel.EMERGENCY]: FeaturePriority.CRITICAL
}
},
resourceLimits: {
cpu: {
[ServiceQualityLevel.OPTIMAL]: 80,
[ServiceQualityLevel.REDUCED]: 60,
[ServiceQualityLevel.MINIMAL]: 40,
[ServiceQualityLevel.CRITICAL]: 30,
[ServiceQualityLevel.EMERGENCY]: 20
},
memory: {
[ServiceQualityLevel.OPTIMAL]: 80,
[ServiceQualityLevel.REDUCED]: 60,
[ServiceQualityLevel.MINIMAL]: 40,
[ServiceQualityLevel.CRITICAL]: 30,
[ServiceQualityLevel.EMERGENCY]: 20
},
bandwidth: {
[ServiceQualityLevel.OPTIMAL]: 1000,
[ServiceQualityLevel.REDUCED]: 500,
[ServiceQualityLevel.MINIMAL]: 200,
[ServiceQualityLevel.CRITICAL]: 50,
[ServiceQualityLevel.EMERGENCY]: 10
},
storageIops: {
[ServiceQualityLevel.OPTIMAL]: 1000,
[ServiceQualityLevel.REDUCED]: 500,
[ServiceQualityLevel.MINIMAL]: 200,
[ServiceQualityLevel.CRITICAL]: 50,
[ServiceQualityLevel.EMERGENCY]: 10
}
},
...config
};
this.currentQualityLevel = this.config.defaultQualityLevel;
this.metrics = this.initializeMetrics();
// Initialize quality level timestamps
Object.values(ServiceQualityLevel).forEach(level => {
this.qualityLevelTimestamps.set(level, 0);
});
this.qualityLevelTimestamps.set(this.currentQualityLevel, Date.now());
}
/**
* Register a feature toggle
*/
registerFeature(feature: FeatureToggle): void {
this.featureToggles.set(feature.id, feature);
this.updateMetrics();
this.emitEvent('recovery', `feature-${feature.id}`, {
action: 'feature_registered',
featureId: feature.id,
featureName: feature.name,
priority: feature.priority,
enabled: feature.enabled
}, 'info');
// Apply current quality level to the feature
this.applyQualityLevelToFeature(feature);
}
/**
* Unregister a feature toggle
*/
unregisterFeature(featureId: string): boolean {
const feature = this.featureToggles.get(featureId);
if (!feature) {
return false;
}
this.featureToggles.delete(featureId);
this.updateMetrics();
this.emitEvent('recovery', `feature-${featureId}`, {
action: 'feature_unregistered',
featureId
}, 'info');
return true;
}
/**
* Check if a feature is enabled
*/
isFeatureEnabled(featureId: string): boolean {
const feature = this.featureToggles.get(featureId);
return feature ? feature.enabled : false;
}
/**
* Manually enable a feature
*/
enableFeature(featureId: string): boolean {
const feature = this.featureToggles.get(featureId);
if (!feature || !feature.manualToggleAllowed) {
return false;
}
if (!feature.enabled) {
feature.enabled = true;
this.updateMetrics();
this.emitEvent('recovery', `feature-${featureId}`, {
action: 'feature_enabled',
featureId,
featureName: feature.name,
manual: true
}, 'info');
}
return true;
}
/**
* Manually disable a feature
*/
disableFeature(featureId: string): boolean {
const feature = this.featureToggles.get(featureId);
if (!feature || !feature.manualToggleAllowed) {
return false;
}
// Don't disable critical features in emergency mode
if (this.currentQualityLevel === ServiceQualityLevel.EMERGENCY &&
feature.priority === FeaturePriority.CRITICAL) {
return false;
}
if (feature.enabled) {
feature.enabled = false;
this.updateMetrics();
this.emitEvent('recovery', `feature-${featureId}`, {
action: 'feature_disabled',
featureId,
featureName: feature.name,
manual: true
}, 'info');
}
return true;
}
/**
* Get current service quality level
*/
getQualityLevel(): ServiceQualityLevel {
return this.currentQualityLevel;
}
/**
* Set service quality level manually
*/
setQualityLevel(level: ServiceQualityLevel): void {
if (level === this.currentQualityLevel) {
return;
}
const previousLevel = this.currentQualityLevel;
this.currentQualityLevel = level;
// Update quality level timestamps
const now = Date.now();
const timeInPreviousLevel = now - this.lastQualityUpdateTime;
const previousTime = this.qualityLevelTimestamps.get(previousLevel) || 0;
this.qualityLevelTimestamps.set(previousLevel, previousTime + timeInPreviousLevel);
this.lastQualityUpdateTime = now;
// Apply quality level to all features
this.applyQualityLevelToAllFeatures();
// Update metrics
this.metrics.previousQualityLevel = previousLevel;
this.metrics.currentQualityLevel = level;
this.metrics.qualityLevelChanges++;
this.updateMetrics();
this.emitEvent('recovery', 'degradation-manager', {
action: 'quality_level_changed',
previousLevel,
newLevel: level,
manual: true
}, 'warning');
}
/**
* Update marine environment for adaptive degradation
*/
updateMarineEnvironment(environment: MarineEnvironmentStatus): void {
this.marineEnvironment = environment;
// Update marine-specific metrics
if (environment.seaState === 'rough' || environment.seaState === 'very_rough') {
this.metrics.marineMetrics.timeInRoughSeas += Date.now() - this.lastQualityUpdateTime;
}
if (environment.powerStatus === 'conservation' || environment.powerStatus === 'critical') {
this.metrics.marineMetrics.timeInPowerConservation += Date.now() - this.lastQualityUpdateTime;
}
if (environment.connectivityQuality < this.config.qualityThresholds.connectivityQuality.low) {
this.metrics.marineMetrics.timeWithPoorConnectivity += Date.now() - this.lastQualityUpdateTime;
}
if (environment.criticalOperationsOnly) {
this.metrics.marineMetrics.timeInEmergencyMode += Date.now() - this.lastQualityUpdateTime;
}
this.lastQualityUpdateTime = Date.now();
// Determine appropriate quality level based on marine conditions
const newQualityLevel = this.determineQualityLevelFromEnvironment(environment);
if (newQualityLevel !== this.currentQualityLevel) {
const previousLevel = this.currentQualityLevel;
this.currentQualityLevel = newQualityLevel;
// Update quality level timestamps
const now = Date.now();
const timeInPreviousLevel = now - this.lastQualityUpdateTime;
const previousTime = this.qualityLevelTimestamps.get(previousLevel) || 0;
this.qualityLevelTimestamps.set(previousLevel, previousTime + timeInPreviousLevel);
this.lastQualityUpdateTime = now;
// Apply quality level to all features
this.applyQualityLevelToAllFeatures();
// Update metrics
this.metrics.previousQualityLevel = previousLevel;
this.metrics.currentQualityLevel = newQualityLevel;
this.metrics.qualityLevelChanges++;
this.emitEvent('recovery', 'degradation-manager', {
action: 'quality_level_changed',
previousLevel,
newLevel: newQualityLevel,
manual: false,
environmentalCause: true,
seaState: environment.seaState,
powerStatus: environment.powerStatus,
connectivityQuality: environment.connectivityQuality,
criticalOperationsOnly: environment.criticalOperationsOnly
}, 'warning');
}
this.emitEvent('recovery', 'degradation-manager', {
action: 'marine_environment_updated',
seaState: environment.seaState,
powerStatus: environment.powerStatus,
connectivityQuality: environment.connectivityQuality,
criticalOperationsOnly: environment.criticalOperationsOnly
}, 'info');
}
/**
* Get current degradation metrics
*/
getMetrics(): DegradationMetrics {
this.updateMetrics();
return { ...this.metrics };
}
/**
* Get all registered features
*/
getAllFeatures(): FeatureToggle[] {
return Array.from(this.featureToggles.values());
}
/**
* Get enabled features
*/
getEnabledFeatures(): FeatureToggle[] {
return Array.from(this.featureToggles.values()).filter(feature => feature.enabled);
}
/**
* Get disabled features
*/
getDisabledFeatures(): FeatureToggle[] {
return Array.from(this.featureToggles.values()).filter(feature => !feature.enabled);
}
/**
* Add event listener
*/
onEvent(listener: (event: ResilienceEvent) => void): void {
this.eventListeners.push(listener);
}
/**
* Remove event listener
*/
removeEventListener(listener: (event: ResilienceEvent) => void): void {
const index = this.eventListeners.indexOf(listener);
if (index > -1) {
this.eventListeners.splice(index, 1);
}
}
/**
* Determine quality level from marine environment
*/
private determineQualityLevelFromEnvironment(environment: MarineEnvironmentStatus): ServiceQualityLevel {
// Start with default quality level
let qualityLevel = this.config.defaultQualityLevel;
// Emergency mode takes precedence
if (environment.criticalOperationsOnly) {
return ServiceQualityLevel.EMERGENCY;
}
// Check power status if configured
if (this.config.powerAware) {
if (environment.powerStatus === 'critical') {
qualityLevel = this.getMoreRestrictiveLevel(
qualityLevel,
this.config.qualityThresholds.powerStatus.critical
);
} else if (environment.powerStatus === 'conservation') {
qualityLevel = this.getMoreRestrictiveLevel(
qualityLevel,
this.config.qualityThresholds.powerStatus.conservation
);
}
}
// Check sea state if configured
if (this.config.adaptToMarineConditions) {
if (environment.seaState === 'very_rough') {
qualityLevel = this.getMoreRestrictiveLevel(
qualityLevel,
this.config.qualityThresholds.seaState.veryRough
);
} else if (environment.seaState === 'rough') {
qualityLevel = this.getMoreRestrictiveLevel(
qualityLevel,
this.config.qualityThresholds.seaState.rough
);
}
}
// Check connectivity quality if configured
if (this.config.connectivityAware) {
if (environment.connectivityQuality < this.config.qualityThresholds.connectivityQuality.veryLow) {
qualityLevel = this.getMoreRestrictiveLevel(
qualityLevel,
this.config.qualityThresholds.connectivityQuality.veryLowQualityLevel
);
} else if (environment.connectivityQuality < this.config.qualityThresholds.connectivityQuality.low) {
qualityLevel = this.getMoreRestrictiveLevel(
qualityLevel,
this.config.qualityThresholds.connectivityQuality.lowQualityLevel
);
}
}
return qualityLevel;
}
/**
* Get the more restrictive of two quality levels
*/
private getMoreRestrictiveLevel(level1: ServiceQualityLevel, level2: ServiceQualityLevel): ServiceQualityLevel {
const levelOrder = [
ServiceQualityLevel.OPTIMAL,
ServiceQualityLevel.REDUCED,
ServiceQualityLevel.MINIMAL,
ServiceQualityLevel.CRITICAL,
ServiceQualityLevel.EMERGENCY
];
const index1 = levelOrder.indexOf(level1);
const index2 = levelOrder.indexOf(level2);
// Ensure we don't return undefined
return levelOrder[Math.max(index1, index2)] || ServiceQualityLevel.OPTIMAL;
}
/**
* Apply quality level to all features
*/
private applyQualityLevelToAllFeatures(): void {
if (!this.config.featureToggles.autoToggleFeatures) {
return;
}
for (const feature of this.featureToggles.values()) {
this.applyQualityLevelToFeature(feature);
}
}
/**
* Apply quality level to a specific feature
*/
private applyQualityLevelToFeature(feature: FeatureToggle): void {
if (!this.config.featureToggles.autoToggleFeatures || !feature.manualToggleAllowed) {
return;
}
const minPriority = this.config.featureToggles.qualityLevelMinPriority[this.currentQualityLevel];
const priorityOrder = [
FeaturePriority.COMFORT,
FeaturePriority.USEFUL,
FeaturePriority.IMPORTANT,
FeaturePriority.ESSENTIAL,
FeaturePriority.CRITICAL
];
const featurePriorityIndex = priorityOrder.indexOf(feature.priority);
const minPriorityIndex = priorityOrder.indexOf(minPriority);
const shouldBeEnabled = featurePriorityIndex >= minPriorityIndex;
// Special case for marine-specific features
if (this.marineEnvironment) {
// Always enable safety features in rough seas
if (feature.marineSettings.requiredForSafety &&
(this.marineEnvironment.seaState === 'rough' ||
this.marineEnvironment.seaState === 'very_rough')) {
if (!feature.enabled) {
feature.enabled = true;
this.emitEvent('recovery', `feature-${feature.id}`, {
action: 'feature_enabled',
featureId: feature.id,
featureName: feature.name,
reason: 'safety_required_in_rough_seas',
manual: false
}, 'info');
}
return;
}
// Always enable navigation features when sailing or motoring
if (feature.marineSettings.requiredForNavigation &&
(this.marineEnvironment.seaState === 'rough' ||
this.marineEnvironment.seaState === 'very_rough')) {
if (!feature.enabled) {
feature.enabled = true;
this.emitEvent('recovery', `feature-${feature.id}`, {
action: 'feature_enabled',
featureId: feature.id,
featureName: feature.name,
reason: 'navigation_required_in_rough_seas',
manual: false
}, 'info');
}
return;
}
// Disable connectivity-dependent features when connectivity is poor
if (feature.marineSettings.requiresGoodConnectivity &&
this.marineEnvironment.connectivityQuality < this.config.qualityThresholds.connectivityQuality.low) {
if (feature.enabled) {
feature.enabled = false;
this.emitEvent('recovery', `feature-${feature.id}`, {
action: 'feature_disabled',
featureId: feature.id,
featureName: feature.name,
reason: 'poor_connectivity',
manual: false
}, 'info');
}
return;
}
}
// Apply standard priority-based rules
if (feature.enabled !== shouldBeEnabled) {
feature.enabled = shouldBeEnabled;
this.emitEvent('recovery', `feature-${feature.id}`, {
action: shouldBeEnabled ? 'feature_enabled' : 'feature_disabled',
featureId: feature.id,
featureName: feature.name,
reason: 'quality_level_change',
qualityLevel: this.currentQualityLevel,
featurePriority: feature.priority,
minPriority,
manual: false
}, 'info');
}
}
/**
* Update metrics
*/
private updateMetrics(): void {
// Update time at quality level
const now = Date.now();
const timeInCurrentLevel = now - this.lastQualityUpdateTime;
const currentTime = this.qualityLevelTimestamps.get(this.currentQualityLevel) || 0;
this.qualityLevelTimestamps.set(this.currentQualityLevel, currentTime + timeInCurrentLevel);
this.lastQualityUpdateTime = now;
// Update time at quality level metrics
Object.values(ServiceQualityLevel).forEach(level => {
this.metrics.timeAtQualityLevel[level] = this.qualityLevelTimestamps.get(level) || 0;
});
// Update feature toggle metrics
const features = Array.from(this.featureToggles.values());
this.metrics.featureToggles.total = features.length;
this.metrics.featureToggles.enabled = features.filter(f => f.enabled).length;
this.metrics.featureToggles.disabled = features.filter(f => !f.enabled).length;
// Update resource usage metrics
let totalCpu = 0;
let totalMemory = 0;
let totalBandwidth = 0;
let totalStorageIops = 0;
let totalPower = 0;
for (const feature of features) {
if (feature.enabled) {
totalCpu += feature.cpuUsage;
totalMemory += feature.memoryUsage;
totalBandwidth += feature.bandwidthUsage;
totalStorageIops += feature.storageIops;
totalPower += feature.powerConsumption;
}
}
this.metrics.resourceUsage.cpu = totalCpu;
this.metrics.resourceUsage.memory = totalMemory;
this.metrics.resourceUsage.bandwidth = totalBandwidth;
this.metrics.resourceUsage.storageIops = totalStorageIops;
this.metrics.resourceUsage.power = totalPower;
}
/**
* Initialize metrics
*/
private initializeMetrics(): DegradationMetrics {
return {
currentQualityLevel: ServiceQualityLevel.OPTIMAL,
previousQualityLevel: ServiceQualityLevel.OPTIMAL,
timeAtQualityLevel: {
[ServiceQualityLevel.OPTIMAL]: 0,
[ServiceQualityLevel.REDUCED]: 0,
[ServiceQualityLevel.MINIMAL]: 0,
[ServiceQualityLevel.CRITICAL]: 0,
[ServiceQualityLevel.EMERGENCY]: 0
},
qualityLevelChanges: 0,
featureToggles: {
total: 0,
enabled: 0,
disabled: 0,
autoToggled: 0,
manuallyToggled: 0
},
resourceUsage: {
cpu: 0,
memory: 0,
bandwidth: 0,
storageIops: 0,
power: 0
},
marineMetrics: {
timeInRoughSeas: 0,
timeInPowerConservation: 0,
timeWithPoorConnectivity: 0,
timeInEmergencyMode: 0
}
};
}
/**
* Emit resilience event
*/
private emitEvent(
eventType: ResilienceEvent['eventType'],
component: string,
details: Record<string, any>,
severity: ResilienceEvent['severity']
): void {
const event: ResilienceEvent = {
timestamp: new Date(),
eventType,
component,
details,
severity,
marineContext: {
operationalContext: this.marineEnvironment?.powerStatus === 'critical' ?
OperationalContext.EMERGENCY : OperationalContext.SAILING,
environmentalImpact: this.marineEnvironment?.seaState === 'very_rough',
safetyImpact: false
}
};
this.eventListeners.forEach(listener => {
try {
listener(event);
} catch (error) {
console.error('Error in degradation manager event listener:', error);
}
});
}
}
/**
* Default degradation manager instance
*/
export const defaultDegradationManager = new DegradationManager();