@sailboat-computer/health-monitoring
Version:
Comprehensive health monitoring system for sailboat computer v3 with marine-specific health checks
312 lines (263 loc) ⢠9.26 kB
text/typescript
/**
* Self-Healing Example
* Demonstrates the integration of health monitoring and recovery mechanisms
*/
import {
HealthCheckEngine,
defaultHealthCheckEngine,
OperationalContext,
MarineEnvironmentStatus,
HealthMonitoringEvent,
HealthStatus
} from '../index';
import {
GPSHealthCheck,
createGPSHealthCheck,
GPSData
} from '../marine/GPSHealthCheck';
import {
RecoveryOrchestrator,
defaultRecoveryOrchestrator
} from '../recovery/RecoveryOrchestrator';
import {
GPSRecalibrationAction,
createGPSRecalibrationAction
} from '../recovery/actions/GPSRecalibrationAction';
import {
registerGPSRecoveryPolicies
} from '../recovery/policies/GPSRecoveryPolicy';
/**
* Self-healing example for marine systems
*/
export class SelfHealingExample {
private healthEngine: HealthCheckEngine;
private recoveryOrchestrator: RecoveryOrchestrator;
private gpsHealthCheck!: GPSHealthCheck;
private gpsRecalibrationAction!: GPSRecalibrationAction;
// Simulated GPS state
private gpsState = {
satelliteCount: 8,
hdop: 1.2,
fix: '3d' as '3d' | '2d' | 'none',
isCalibrated: true
};
constructor() {
this.healthEngine = defaultHealthCheckEngine;
this.recoveryOrchestrator = defaultRecoveryOrchestrator;
// Set up event handling
this.setupEventHandling();
// Initialize health checks and recovery actions
this.initializeHealthChecks();
this.initializeRecoveryActions();
}
/**
* Initialize health checks
*/
private initializeHealthChecks(): void {
// Create GPS health check
this.gpsHealthCheck = createGPSHealthCheck(
this.mockGPSDataProvider.bind(this)
);
// Register with health engine
this.healthEngine.registerHealthCheck(this.gpsHealthCheck);
}
/**
* Initialize recovery actions and policies
*/
private initializeRecoveryActions(): void {
// Create GPS recalibration action
this.gpsRecalibrationAction = createGPSRecalibrationAction({
resetSatelliteTracking: async () => {
console.log('š ļø GPS: Resetting satellite tracking');
await this.wait(1000);
return true;
},
clearAlmanac: async () => {
console.log('š ļø GPS: Clearing almanac data');
await this.wait(1000);
return true;
},
resetHDOPThresholds: async () => {
console.log('š ļø GPS: Resetting HDOP thresholds');
await this.wait(1000);
return true;
},
forceColdStart: async () => {
console.log('š ļø GPS: Forcing cold start');
await this.wait(2000);
return true;
},
waitForSatellites: async (timeout: number) => {
console.log(`š ļø GPS: Waiting for satellites (timeout: ${timeout}s)`);
await this.wait(2000);
// Recalibration improves satellite count
this.gpsState.satelliteCount = Math.min(12, this.gpsState.satelliteCount + 4);
this.gpsState.hdop = Math.max(0.8, this.gpsState.hdop - 0.4);
this.gpsState.isCalibrated = true;
return this.gpsState.satelliteCount;
}
});
// Register recovery action
this.recoveryOrchestrator.registerRecoveryAction(this.gpsRecalibrationAction);
// Register recovery policies
registerGPSRecoveryPolicies(
policy => this.recoveryOrchestrator.registerRecoveryPolicy(policy)
);
}
/**
* Set up event handling
*/
private setupEventHandling(): void {
// Listen for health monitoring events
this.healthEngine.onEvent((event: HealthMonitoringEvent) => {
console.log(`[${event.timestamp.toISOString()}] Health Event: ${event.eventType}`);
console.log(` System: ${event.systemId}, Check: ${event.checkId}`);
console.log(` Status: ${event.currentStatus}`);
// Forward health check results to recovery orchestrator
if (event.eventType === 'health_check_completed' && event.data) {
const results = this.healthEngine.getAllResults();
const checkResult = event.checkId ? results.get(event.checkId) : undefined;
if (checkResult) {
this.recoveryOrchestrator.processHealthCheckResult(checkResult);
}
}
});
// Listen for recovery events
this.recoveryOrchestrator.onEvent((event) => {
console.log(`[${event.timestamp.toISOString()}] Recovery Event: ${event.eventType}`);
console.log(` System: ${event.systemId}, Policy: ${event.policyId || 'none'}`);
console.log(` Message: ${event.data.message}`);
if (event.result) {
console.log(` Result: ${event.result.success ? 'Success' : 'Failed'}`);
if (event.result.details) {
console.log(` Details: ${JSON.stringify(event.result.details)}`);
}
}
});
}
/**
* Start the self-healing system
*/
public start(): void {
console.log('š¢ Starting Self-Healing System...');
// Set initial operational context
this.healthEngine.updateOperationalContext(OperationalContext.SAILING);
this.recoveryOrchestrator.updateOperationalContext(OperationalContext.SAILING);
// Set initial marine environment
const environment: MarineEnvironmentStatus = {
seaState: 'moderate',
weather: 'clear',
windSpeed: 12,
temperature: 22,
powerStatus: 'normal',
connectivityQuality: 0.9,
expectedFailureRate: 1.0,
recommendedTimeoutMultiplier: 1.0,
criticalOperationsOnly: false
};
this.healthEngine.updateMarineEnvironment(environment);
this.recoveryOrchestrator.updateMarineEnvironment(environment);
// Start the health check engine
this.healthEngine.start();
console.log('ā
Self-Healing System started');
}
/**
* Stop the self-healing system
*/
public stop(): void {
console.log('š Stopping Self-Healing System...');
this.healthEngine.stop();
console.log('ā
Self-Healing System stopped');
}
/**
* Simulate GPS degradation
*/
public simulateGPSDegradation(): void {
console.log('š Simulating GPS degradation...');
// Degrade GPS state
this.gpsState.satelliteCount = 3;
this.gpsState.hdop = 4.5;
this.gpsState.isCalibrated = false;
console.log(`š GPS degraded: ${this.gpsState.satelliteCount} satellites, HDOP: ${this.gpsState.hdop}`);
}
/**
* Simulate GPS failure
*/
public simulateGPSFailure(): void {
console.log('š Simulating GPS failure...');
// Fail GPS
this.gpsState.satelliteCount = 0;
this.gpsState.hdop = 10.0;
this.gpsState.fix = '2d' as const; // Changed from 'none' to valid enum value
this.gpsState.isCalibrated = false;
console.log('š GPS failed: No satellite fix');
}
/**
* Simulate GPS recovery
*/
public simulateGPSRecovery(): void {
console.log('š Simulating GPS recovery...');
// Recover GPS
this.gpsState.satelliteCount = 9;
this.gpsState.hdop = 1.0;
this.gpsState.fix = '3d' as const;
this.gpsState.isCalibrated = true;
console.log(`š GPS recovered: ${this.gpsState.satelliteCount} satellites, HDOP: ${this.gpsState.hdop}`);
}
/**
* Mock GPS data provider
*/
private async mockGPSDataProvider(): Promise<GPSData> {
return {
latitude: 37.7749 + (Math.random() - 0.5) * 0.001,
longitude: -122.4194 + (Math.random() - 0.5) * 0.001,
altitude: 10 + Math.random() * 5,
satelliteCount: this.gpsState.satelliteCount,
hdop: this.gpsState.hdop,
vdop: this.gpsState.hdop * 1.2,
speed: Math.random() * 10,
course: Math.random() * 360,
timestamp: new Date(),
fix: this.gpsState.fix
};
}
/**
* Utility function to wait
*/
private wait(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
/**
* Run the self-healing example
*/
export async function runSelfHealingExample(): Promise<void> {
const example = new SelfHealingExample();
try {
// Start the self-healing system
example.start();
// Wait for initial health checks
console.log('\nā±ļø Waiting for initial health checks...');
await new Promise(resolve => setTimeout(resolve, 3000));
// Simulate GPS degradation
example.simulateGPSDegradation();
console.log('\nā±ļø Waiting for health checks to detect degradation...');
await new Promise(resolve => setTimeout(resolve, 5000));
// Simulate GPS failure
example.simulateGPSFailure();
console.log('\nā±ļø Waiting for health checks to detect failure...');
await new Promise(resolve => setTimeout(resolve, 5000));
// Simulate GPS recovery
example.simulateGPSRecovery();
console.log('\nā±ļø Waiting for health checks to detect recovery...');
await new Promise(resolve => setTimeout(resolve, 5000));
// Keep running for a bit to see ongoing monitoring
console.log('\nā±ļø Running continuous monitoring for 10 seconds...');
await new Promise(resolve => setTimeout(resolve, 10000));
} finally {
// Clean shutdown
example.stop();
}
}
// Export for easy testing
export default SelfHealingExample;