UNPKG

@bernierllc/retry-policy

Version:

Atomic retry policy utilities with exponential backoff and jitter

250 lines (216 loc) 7.36 kB
#!/usr/bin/env node /* Copyright (c) 2025 Bernier LLC This file is licensed to the client under a limited-use license. The client may use and modify this code *only within the scope of the project it was delivered for*. Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC. */ /** * Configuration initialization script for @bernierllc/retry-policy core package * * Usage: npm run config:init */ const fs = require('fs'); const path = require('path'); // Package configuration const PACKAGE_NAME = 'retry-policy'; const PACKAGE_TYPE = 'core'; const CONFIG_FILE = `${PACKAGE_NAME}.config.js`; // Configuration template const CONFIG_TEMPLATE = `/* Copyright (c) 2025 Bernier LLC This file is licensed to the client under a limited-use license. The client may use and modify this code *only within the scope of the project it was delivered for*. Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC. */ /** * @bernierllc/retry-policy configuration * * This is a behavioral core package that supports optional runtime configuration * while maintaining full backward compatibility. All settings are optional. */ module.exports = { // ============================================= // RETRY POLICY CONFIGURATION // ============================================= /** * Maximum number of retry attempts * @default 5 * Environment: RETRY_MAX_RETRIES */ maxRetries: 3, /** * Initial delay in milliseconds before first retry * @default 1000 * Environment: RETRY_INITIAL_DELAY */ initialDelayMs: 1000, /** * Maximum delay in milliseconds (prevents infinite backoff) * @default 30000 * Environment: RETRY_MAX_DELAY */ maxDelayMs: 30000, /** * Exponential backoff factor * @default 2 * Environment: RETRY_BACKOFF_FACTOR */ backoffFactor: 2.0, /** * Enable/disable jitter to prevent thundering herd * @default true * Environment: RETRY_JITTER */ jitter: true, /** * Enable/disable retry functionality globally * Setting to false will disable all retries * @default true * Environment: RETRY_ENABLED */ enabled: true, // ============================================= // BACKOFF STRATEGY CONFIGURATION // ============================================= /** * Backoff strategy configuration */ backoff: { /** * Backoff strategy type * Values: 'exponential' | 'linear' | 'constant' * @default 'exponential' * Environment: RETRY_BACKOFF_TYPE */ type: 'exponential', /** * Base delay for backoff calculations * @default 1000 * Environment: RETRY_BACKOFF_BASE_DELAY */ baseDelay: 1000, /** * Maximum delay cap * @default 30000 * Environment: RETRY_BACKOFF_MAX_DELAY */ maxDelay: 30000, /** * Backoff multiplier for exponential strategy * @default 2 * Environment: RETRY_BACKOFF_MULTIPLIER */ factor: 2.0, /** * Jitter configuration */ jitter: { /** * Jitter type * Values: 'none' | 'full' | 'equal' | 'decorrelated' * @default 'full' * Environment: RETRY_JITTER_TYPE */ type: 'full', /** * Jitter factor (0-1) * @default 0.1 * Environment: RETRY_JITTER_FACTOR */ factor: 0.1 } } // ============================================= // NOTES FOR CORE PACKAGE CONFIGURATION // ============================================= /* * Core Package Principles: * - Configuration is OPTIONAL - package works perfectly without it * - No breaking changes - all existing usage patterns continue to work * - Constructor parameters take precedence over configuration * - Service packages can inject global configuration * * Service Package Integration: * Service packages can configure this core package globally: * * import { setGlobalRetryPolicyConfig } from '@bernierllc/retry-policy'; * * setGlobalRetryPolicyConfig({ * maxRetries: 5, * initialDelayMs: 500, * backoff: { type: 'exponential', factor: 1.5 } * }); * * Configuration Precedence (lowest to highest): * 1. Package defaults * 2. Global configuration (from service packages) * 3. Configuration file (this file) * 4. Environment variables * 5. Constructor parameters (highest priority) */ }; `; class ConfigurationInitializer { constructor() { this.configPath = path.join(process.cwd(), CONFIG_FILE); } initialize() { console.log(`🔧 Initializing configuration for ${PACKAGE_NAME} (${PACKAGE_TYPE} package)`); console.log(''); // Check if configuration file already exists if (fs.existsSync(this.configPath)) { console.log(`⚠️ Configuration file already exists: ${CONFIG_FILE}`); console.log(' Use --force to overwrite existing configuration'); const forceOverwrite = process.argv.includes('--force'); if (!forceOverwrite) { console.log(''); console.log('💡 To view current configuration:'); console.log(` npm run config:print`); console.log(''); console.log('💡 To validate configuration:'); console.log(` npm run config:validate`); return; } } try { // Write configuration file fs.writeFileSync(this.configPath, CONFIG_TEMPLATE, 'utf8'); console.log(`✅ Created configuration file: ${CONFIG_FILE}`); console.log(''); console.log('📋 Configuration includes:'); console.log(' • Optional runtime configuration for behavioral core package'); console.log(' • Retry policy settings (attempts, delays, backoff strategies)'); console.log(' • Global enable/disable functionality'); console.log(' • Service package integration support'); console.log(' • Full backward compatibility'); console.log(''); console.log('🔧 Available commands:'); console.log(` npm run config:print - Print resolved configuration`); console.log(` npm run config:validate - Validate configuration`); console.log(''); console.log('🌍 Environment variables (optional):'); console.log(' RETRY_MAX_RETRIES - Maximum retry attempts'); console.log(' RETRY_INITIAL_DELAY - Initial delay in ms'); console.log(' RETRY_ENABLED - Enable/disable retries'); console.log(' RETRY_BACKOFF_TYPE - Backoff strategy (exponential/linear/constant)'); console.log(''); console.log('🔗 Service Package Integration:'); console.log(' Service packages can configure this core package using:'); console.log(' setGlobalRetryPolicyConfig({ maxRetries: 5, ... })'); console.log(''); console.log('📖 See README.md for complete documentation and usage examples'); } catch (error) { console.error('❌ Failed to create configuration file:', error.message); process.exit(1); } } } function main() { const initializer = new ConfigurationInitializer(); initializer.initialize(); } if (require.main === module) { main(); } module.exports = { ConfigurationInitializer };