digital-samba-mcp-server
Version:
Digital Samba MCP Server - Model Context Protocol server for Digital Samba's video conferencing API
329 lines • 10.3 kB
TypeScript
/**
* Graceful Degradation Module
*
* This module provides mechanisms for handling partial API outages and ensuring
* continued functionality with degraded service levels. It works alongside the
* circuit breaker pattern to provide a comprehensive approach to API resilience.
*
* Key features:
* - Multiple degradation levels based on service health
* - Fallback strategies for critical functionality
* - Cached content serving during outages
* - Intelligent retry mechanisms with exponential backoff
* - Health monitoring and automatic recovery
* - Metrics integration for observability
*
* @module graceful-degradation
* @author Digital Samba Team
* @version 0.1.0
*/
import { EventEmitter } from 'events';
import { MemoryCache } from './cache.js';
/**
* Service health status levels
*/
export declare enum ServiceHealthStatus {
HEALTHY = "HEALTHY",// All systems operational
PARTIALLY_DEGRADED = "PARTIALLY_DEGRADED",// Some non-critical systems affected
SEVERELY_DEGRADED = "SEVERELY_DEGRADED",// Critical systems affected
UNAVAILABLE = "UNAVAILABLE"
}
/**
* Service component health tracking
*/
export interface ServiceComponentHealth {
name: string;
status: ServiceHealthStatus;
lastCheck: Date;
errorCount: number;
message?: string;
}
/**
* Fallback strategy type
*
* Defines a function that provides alternative functionality
* when a primary service is unavailable
*/
export type FallbackStrategy<T> = () => Promise<T>;
/**
* Degradation options interface
*/
export interface GracefulDegradationOptions {
/**
* Cache instance for storing fallback data
*/
cache?: MemoryCache;
/**
* Maximum number of retry attempts for failed operations
* @default 3
*/
maxRetryAttempts?: number;
/**
* Initial delay in milliseconds before first retry
* @default 1000 (1 second)
*/
initialRetryDelay?: number;
/**
* Factor to multiply delay by for each subsequent retry
* @default 2 (exponential backoff)
*/
retryBackoffFactor?: number;
/**
* Maximum delay in milliseconds between retries
* @default 30000 (30 seconds)
*/
maxRetryDelay?: number;
/**
* Interval in milliseconds to check service health
* @default 60000 (1 minute)
*/
healthCheckInterval?: number;
/**
* Component failure threshold before considering the component degraded
* @default 3
*/
componentFailureThreshold?: number;
/**
* Component success threshold before considering the component recovered
* @default 2
*/
componentRecoveryThreshold?: number;
}
/**
* Fallback configuration interface
*/
export interface FallbackConfig<T> {
/**
* The fallback function to call when the primary operation fails
*/
fallbackFn: FallbackStrategy<T>;
/**
* Is this operation critical for the application
* @default false
*/
isCritical?: boolean;
/**
* TTL for cached fallback data in milliseconds
* @default 300000 (5 minutes)
*/
cacheTTL?: number;
/**
* Indicates whether the fallback is currently active
* @default false
*/
isActive?: boolean;
}
/**
* Operation result with degradation information
*/
export interface DegradedResult<T> {
/**
* The operation result data
*/
data: T;
/**
* Indicates if the result comes from a degraded service
*/
isDegraded: boolean;
/**
* Degradation level if applicable
*/
degradationLevel?: ServiceHealthStatus;
/**
* Source of the data (primary, cache, fallback)
*/
source: 'primary' | 'cache' | 'fallback';
/**
* Optional message about the degradation
*/
message?: string;
}
/**
* Graceful degradation service for handling API outages
*
* This class provides mechanisms for handling partial API outages and ensuring
* the application can continue functioning with degraded service levels.
*
* @class GracefulDegradation
* @example
* // Create a graceful degradation service
* const degradationService = new GracefulDegradation({
* cache: new MemoryCache(),
* maxRetryAttempts: 3,
* initialRetryDelay: 1000
* });
*
* // Register a fallback for the listRooms operation
* degradationService.registerFallback('listRooms', {
* fallbackFn: async () => ({ data: [], total_count: 0, length: 0, map: () => [] }),
* isCritical: true
* });
*
* // Execute an operation with graceful degradation
* const result = await degradationService.executeWithFallback(
* 'listRooms',
* () => apiClient.listRooms(),
* { cacheKey: 'rooms' }
* );
*/
export declare class GracefulDegradation extends EventEmitter {
private cache?;
private maxRetryAttempts;
private initialRetryDelay;
private retryBackoffFactor;
private maxRetryDelay;
private healthCheckInterval;
private componentFailureThreshold;
private componentRecoveryThreshold;
private healthCheckTimer?;
private fallbacks;
private componentHealth;
private overallHealth;
/**
* Creates a new GracefulDegradation instance
*
* @constructor
* @param {GracefulDegradationOptions} options - Configuration options
*/
constructor(options?: GracefulDegradationOptions);
/**
* Start periodic health checks
*
* @private
*/
private startHealthCheck;
/**
* Stop periodic health checks
*
* @private
*/
private stopHealthCheck;
/**
* Cleanup resources - call when shutting down
*/
dispose(): void;
/**
* Monitor circuit breakers to detect component health
*
* @private
*/
private monitorCircuitBreakers;
/**
* Monitor a specific circuit breaker
*
* @private
* @param {CircuitBreaker} circuit - The circuit breaker to monitor
*/
private monitorCircuitBreaker;
/**
* Register a fallback strategy for an operation
*
* @param {string} operationName - The name of the operation
* @param {FallbackConfig<T>} config - The fallback configuration
* @example
* // Register a fallback for the listRooms operation
* degradationService.registerFallback('listRooms', {
* fallbackFn: async () => ({ data: [], total_count: 0, length: 0, map: () => [] }),
* isCritical: true,
* cacheTTL: 600000 // 10 minutes
* });
*/
registerFallback<T>(operationName: string, config: FallbackConfig<T>): void;
/**
* Execute an operation with graceful degradation and fallback support
*
* This method attempts to execute the primary operation, and if it fails,
* it follows a degradation strategy:
* 1. Try to fetch from cache if available
* 2. Retry with exponential backoff if appropriate
* 3. Use the registered fallback if available
* 4. Throw an error if all strategies fail
*
* @template T - The type of the operation result
* @param {string} operationName - The name of the operation (should match the registered fallback)
* @param {() => Promise<T>} primaryFn - The primary operation function
* @param {Object} options - Additional options
* @param {string} [options.cacheKey] - Key to use for caching results
* @param {number} [options.cacheTTL] - TTL for cache in milliseconds
* @param {boolean} [options.skipCache] - Skip cache check
* @param {boolean} [options.skipRetry] - Skip retry attempts
* @returns {Promise<DegradedResult<T>>} The operation result with degradation information
* @throws {DegradedServiceError} If all strategies fail and no fallback is available
* @example
* // Execute a function with graceful degradation
* const result = await degradationService.executeWithFallback(
* 'listRooms',
* () => apiClient.listRooms(),
* { cacheKey: 'rooms', cacheTTL: 300000 }
* );
*
* // Use the result, checking if it's degraded
* if (result.isDegraded) {
* console.log(`Using ${result.source} data due to ${result.degradationLevel} service`);
* }
* const rooms = result.data;
*/
executeWithFallback<T>(operationName: string, primaryFn: () => Promise<T>, options?: {
cacheKey?: string;
cacheTTL?: number;
skipCache?: boolean;
skipRetry?: boolean;
}): Promise<DegradedResult<T>>;
/**
* Update component health status
*
* @private
* @param {string} componentName - The name of the component
* @param {ServiceHealthStatus} status - The new status
*/
private updateComponentHealth;
/**
* Check health of all components
*
* @private
*/
private checkHealth;
/**
* Recalculate overall service health based on component health
*
* @private
*/
private recalculateOverallHealth;
/**
* Get current overall service health
*
* @returns {ServiceHealthStatus} The current overall health status
*/
getOverallHealth(): ServiceHealthStatus;
/**
* Get health of all components
*
* @returns {ServiceComponentHealth[]} Array of component health statuses
*/
getComponentHealth(): ServiceComponentHealth[];
/**
* Get health of a specific component
*
* @param {string} componentName - The name of the component
* @returns {ServiceComponentHealth | undefined} The component health or undefined if not found
*/
getComponentHealthById(componentName: string): ServiceComponentHealth | undefined;
/**
* Update metrics for the graceful degradation service
*
* This method attempts to update Prometheus metrics if the metrics module is available.
* If the metrics module cannot be imported, the method silently ignores the error.
*
* @private
* @param {string} event - The event type
* @param {Record<string, any>} [labels] - Additional labels for the metric
* @param {number} [value] - Value for gauge metrics
*/
private updateMetrics;
}
/**
* Singleton instance of the graceful degradation service
*/
export declare const gracefulDegradation: GracefulDegradation;
export default gracefulDegradation;
//# sourceMappingURL=graceful-degradation.d.ts.map