@bernierllc/retry-policy
Version:
Atomic retry policy utilities with exponential backoff and jitter
320 lines (243 loc) • 8.58 kB
Markdown
# /retry-policy
Atomic retry policy utilities with exponential backoff and jitter support.
## Overview
`/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 /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 /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 /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
- `/retry-state` - Retry state management and persistence
- `/retry-metrics` - Retry performance metrics collection
- `/retry-manager` - High-level retry orchestration service