UNPKG

@bernierllc/retry-policy

Version:

Atomic retry policy utilities with exponential backoff and jitter

320 lines (243 loc) 8.58 kB
# @bernierllc/retry-policy Atomic retry policy utilities with exponential backoff and jitter support. ## Overview `@bernierllc/retry-policy` provides atomic utilities for implementing retry logic with configurable backoff strategies and jitter. This package is designed to be a core building block that can be used by higher-level retry managers and services. ## Features - **Multiple backoff strategies**: Exponential, linear, and constant backoff - **Configurable jitter**: Full, equal, decorrelated, and no jitter options - **Custom retry conditions**: Flexible error evaluation logic - **Type-safe API**: Full TypeScript support with strict typing - **Zero dependencies**: Pure functions with no external dependencies - **Comprehensive testing**: 95%+ test coverage ## Installation ```bash npm install @bernierllc/retry-policy ``` ## Quick Start ```typescript import { RetryPolicy, createRetryPolicy } from '@bernierllc/retry-policy'; // Create a retry policy with default settings const policy = new RetryPolicy(); // Evaluate if an operation should be retried const result = policy.evaluateRetry(1, new Error('Network error')); console.log(result); // { // shouldRetry: true, // delay: 2000, // attempt: 1, // isFinalAttempt: false // } ``` ## API Reference ### RetryPolicy Class The main class for managing retry policies. #### Constructor ```typescript new RetryPolicy(options?: Partial<RetryPolicyOptions>, backoffConfig?: Partial<BackoffConfig>) ``` #### Methods - `evaluateRetry(attempt: number, error: any): RetryPolicyResult` - `calculateDelay(attempt: number): number` - `getOptions(): Required<RetryPolicyOptions>` - `getBackoffConfig(): BackoffConfig` - `updateOptions(options: Partial<RetryPolicyOptions>): void` - `updateBackoffConfig(config: Partial<BackoffConfig>): void` ### Utility Functions - `createRetryPolicy(options?, backoffConfig?): RetryPolicy` - `calculateRetryDelay(attempt, options?, backoffConfig?): number` - `shouldRetry(attempt, error, options?): boolean` ## Usage Examples ### Basic Usage ```typescript import { RetryPolicy } from '@bernierllc/retry-policy'; const policy = new RetryPolicy({ maxRetries: 3, initialDelayMs: 1000, shouldRetry: (error) => error.code === 'NETWORK_ERROR' }); // In your retry loop for (let attempt = 0; attempt <= 3; attempt++) { try { const result = await someOperation(); break; // Success, exit retry loop } catch (error) { const retryResult = policy.evaluateRetry(attempt, error); if (!retryResult.shouldRetry) { throw error; // Don't retry, re-throw error } // Wait before next attempt await new Promise(resolve => setTimeout(resolve, retryResult.delay)); } } ``` ### Custom Backoff Strategy ```typescript import { RetryPolicy } from '@bernierllc/retry-policy'; const policy = new RetryPolicy( { maxRetries: 5 }, { type: 'exponential', baseDelay: 500, factor: 3, maxDelay: 10000, jitter: { type: 'full', factor: 0.1 } } ); // This will use exponential backoff with full jitter const delay = policy.calculateDelay(2); // ~4500ms with jitter ``` ### Different Backoff Types ```typescript import { RetryPolicy } from '@bernierllc/retry-policy'; // Exponential backoff (default) const exponential = new RetryPolicy(undefined, { type: 'exponential', baseDelay: 1000, factor: 2 }); // Delays: 1000ms, 2000ms, 4000ms, 8000ms... // Linear backoff const linear = new RetryPolicy(undefined, { type: 'linear', baseDelay: 1000 }); // Delays: 1000ms, 2000ms, 3000ms, 4000ms... // Constant backoff const constant = new RetryPolicy(undefined, { type: 'constant', baseDelay: 1000 }); // Delays: 1000ms, 1000ms, 1000ms, 1000ms... ``` ### Jitter Types ```typescript import { RetryPolicy } from '@bernierllc/retry-policy'; // Full jitter: random value between 0 and delay const fullJitter = new RetryPolicy(undefined, { jitter: { type: 'full', factor: 0.1 } }); // Equal jitter: random value between delay/2 and delay const equalJitter = new RetryPolicy(undefined, { jitter: { type: 'equal', factor: 0.1 } }); // Decorrelated jitter: random value between delay and delay * 3 const decorrelatedJitter = new RetryPolicy(undefined, { jitter: { type: 'decorrelated', factor: 0.1 } }); // No jitter: exact delay values const noJitter = new RetryPolicy(undefined, { jitter: { type: 'none' } }); ``` ### Custom Retry Conditions ```typescript import { RetryPolicy } from '@bernierllc/retry-policy'; const policy = new RetryPolicy({ maxRetries: 5, shouldRetry: (error) => { // Only retry on network errors or 5xx server errors if (error.code === 'NETWORK_ERROR') return true; if (error.status >= 500 && error.status < 600) return true; return false; }, onRetry: (attempt, delay, error) => { console.log(`Retry attempt ${attempt} after ${delay}ms due to:`, error.message); }, onFailure: (error) => { console.log('All retry attempts exhausted:', error.message); } }); ``` ## Configuration ### RetryPolicyOptions ```typescript interface RetryPolicyOptions { maxRetries: number; // Maximum number of retry attempts initialDelayMs: number; // Initial delay in milliseconds maxDelayMs?: number; // Maximum delay in milliseconds backoffFactor?: number; // Exponential backoff factor jitter?: boolean; // Whether to apply jitter shouldRetry?: (error: any) => boolean; // Custom retry condition onRetry?: (attempt: number, delay: number, error: any) => void; // Retry callback onFailure?: (error: any) => void; // Failure callback } ``` ### BackoffConfig ```typescript interface BackoffConfig { type: 'exponential' | 'linear' | 'constant'; // Backoff strategy baseDelay: number; // Base delay in milliseconds maxDelay: number; // Maximum delay in milliseconds factor?: number; // Backoff factor for exponential jitter?: JitterConfig; // Jitter configuration } ``` ### JitterConfig ```typescript interface JitterConfig { type: 'none' | 'full' | 'equal' | 'decorrelated'; // Jitter type factor?: number; // Jitter factor (0-1) } ``` ## Default Values ```typescript const DEFAULT_RETRY_OPTIONS = { maxRetries: 5, initialDelayMs: 1000, maxDelayMs: 30000, backoffFactor: 2, jitter: true, shouldRetry: () => true, onRetry: () => {}, onFailure: () => {} }; const DEFAULT_BACKOFF_CONFIG = { type: 'exponential', baseDelay: 1000, maxDelay: 30000, factor: 2, jitter: { type: 'full', factor: 0.1 } }; ``` ## Integration Status ### Logger Integration **Status**: not-applicable This is a pure utility core package with no dependencies. Logging is handled by consuming packages. Does not require @bernierllc/logger integration. ### Docs-Suite Integration **Status**: ready Complete API documentation with TypeScript types and examples available for documentation suite integration. ### NeverHub Integration **Status**: not-applicable Pure utility package with no runtime dependencies. NeverHub integration is handled at the service-level packages that consume this utility. Does not require @bernierllc/neverhub-adapter integration. ## Security This package has zero runtime dependencies and uses only pure TypeScript functions. Security considerations: - **No External Dependencies**: All retry logic is implemented internally with no external packages at runtime - **Type Safety**: Strict TypeScript typing prevents common runtime errors - **No Network Calls**: Pure computational functions with no I/O operations - **No Secret Storage**: Does not handle or store any sensitive data - **Audit Clean**: `npm audit` shows no vulnerabilities (zero dependencies) For security concerns, please open an issue in the repository. ## Testing ```bash # Run tests npm test # Run tests with coverage npm run test:coverage # Run tests in watch mode npm run test:watch ``` ## Contributing This package follows the Bernier LLC development standards: - **TypeScript strict mode** - All code must pass strict type checking - **Comprehensive testing** - 95%+ test coverage required - **Documentation** - All public APIs must be documented - **Code style** - Follow project ESLint configuration ## License ISC License - see LICENSE file for details. ## Related Packages - `@bernierllc/retry-state` - Retry state management and persistence - `@bernierllc/retry-metrics` - Retry performance metrics collection - `@bernierllc/retry-manager` - High-level retry orchestration service