UNPKG

self-serve-integration-service

Version:

Self-Serve Integration Service for managing multiple funder integrations including REST APIs, SOAP APIs, and UI automation

127 lines (114 loc) 3.94 kB
/** * Retry Configuration Utility * * Provides dynamic retry configuration from environment variables * with fallback to default values and support for funder-specific overrides. */ export interface RetryConfig { enabled: boolean; maxRetries: number; baseDelay: number; maxDelay: number; backoffMultiplier: number; } /** * Get global retry configuration from environment variables */ export function getGlobalRetryConfig(): RetryConfig { return { enabled: process.env['API_RETRY_ENABLED'] !== 'false', maxRetries: parseInt(process.env['API_MAX_RETRIES'] || '3', 10), baseDelay: parseInt(process.env['API_RETRY_BASE_DELAY'] || '1000', 10), maxDelay: parseInt(process.env['API_RETRY_MAX_DELAY'] || '10000', 10), backoffMultiplier: parseFloat(process.env['API_RETRY_BACKOFF_MULTIPLIER'] || '2'), }; } /** * Get funder-specific retry configuration with fallback to global config * * @param funderName - Name of the funder (e.g., "LEX", "ALPHABET") * @returns RetryConfig with funder-specific overrides applied * * @example * // Get LEX-specific retry config (uses LEX_MAX_RETRIES if set, otherwise API_MAX_RETRIES) * const lexConfig = getFunderRetryConfig('LEX'); * * // Get Alphabet-specific retry config * const alphabetConfig = getFunderRetryConfig('ALPHABET'); */ export function getFunderRetryConfig(funderName: string): RetryConfig { const globalConfig = getGlobalRetryConfig(); const funderPrefix = funderName.toUpperCase(); return { enabled: globalConfig.enabled, maxRetries: parseInt( process.env[`${funderPrefix}_MAX_RETRIES`] || process.env['API_MAX_RETRIES'] || '3', 10 ), baseDelay: parseInt( process.env[`${funderPrefix}_RETRY_BASE_DELAY`] || process.env['API_RETRY_BASE_DELAY'] || '1000', 10 ), maxDelay: parseInt( process.env[`${funderPrefix}_RETRY_MAX_DELAY`] || process.env['API_RETRY_MAX_DELAY'] || '10000', 10 ), backoffMultiplier: parseFloat(process.env['API_RETRY_BACKOFF_MULTIPLIER'] || '2'), }; } /** * Calculate retry delay using exponential backoff * * @param attempt - Current attempt number (1-based) * @param config - Retry configuration * @returns Delay in milliseconds * * @example * // Calculate delay for 3rd attempt with default config * const delay = calculateRetryDelay(3, getGlobalRetryConfig()); * // Returns: min(1000 * 2^2, 10000) = 4000ms */ export function calculateRetryDelay(attempt: number, config: RetryConfig): number { const exponentialDelay = config.baseDelay * Math.pow(config.backoffMultiplier, attempt - 1); return Math.min(exponentialDelay, config.maxDelay); } /** * Check if retry should be attempted based on configuration and attempt count * * @param attempt - Current attempt number (1-based) * @param config - Retry configuration * @returns true if retry should be attempted */ export function shouldRetry(attempt: number, config: RetryConfig): boolean { return config.enabled && attempt < config.maxRetries; } /** * Validate retry configuration * Throws error if configuration is invalid */ export function validateRetryConfig(config: RetryConfig): void { if (config.maxRetries < 0) { throw new Error('maxRetries must be >= 0'); } if (config.baseDelay < 0) { throw new Error('baseDelay must be >= 0'); } if (config.maxDelay < config.baseDelay) { throw new Error('maxDelay must be >= baseDelay'); } if (config.backoffMultiplier < 1) { throw new Error('backoffMultiplier must be >= 1'); } } /** * Format retry configuration for logging */ export function formatRetryConfig(config: RetryConfig): string { return `enabled=${config.enabled}, maxRetries=${config.maxRetries}, baseDelay=${config.baseDelay}ms, maxDelay=${config.maxDelay}ms, multiplier=${config.backoffMultiplier}`; } // Export default global config export default getGlobalRetryConfig();