UNPKG

cronius

Version:

A flexible, powerful cron job orchestrator for Node.js – jobs, retries, dependencies, monitoring

359 lines (285 loc) 9.92 kB
# Cronius A flexible, powerful cron job orchestrator for Node.js with advanced features including job dependencies, retry mechanisms, parallel execution, and comprehensive monitoring. ## Features - **Flexible Scheduling**: Standard cron syntax, human-readable expressions, and one-time execution - **Job Orchestration**: Sequential chains, parallel execution groups, and conditional job execution - **Retry & Error Handling**: Configurable retry attempts with linear or exponential backoff - **Dependencies**: Job dependency management ensuring proper execution order - **Monitoring**: Real-time metrics, event emission, and Prometheus integration - **TypeScript**: Full TypeScript support with comprehensive type definitions - **CLI Interface**: Built-in command-line tool for job management ## Installation ```bash npm install cronius ``` ## Quick Start ### Basic Usage ```typescript import Cronius from 'cronius'; // Create a Cronius instance const cronius = new Cronius({ timezone: 'America/New_York', defaultRetryAttempts: 3, }); // Create a simple job const backupJob = cronius.createJob({ id: 'backup-database', name: 'Database Backup', description: 'Daily database backup at 2 AM', schedule: '0 2 * * *', // Every day at 2:00 AM handler: async (job) => { console.log(`Starting backup job: ${job.id}`); // Your backup logic here return { status: 'completed', timestamp: new Date() }; }, retryAttempts: 3, retryDelay: 5000, retryBackoff: 'exponential', }); // Start the job await backupJob.start(); ``` ### Human-Readable Schedules ```typescript // Run every 5 minutes const frequentJob = cronius.createJob({ id: 'frequent-task', schedule: { every: 5, unit: 'minute' }, handler: async () => console.log('Frequent task executed'), }); // Run every hour at 9:00 AM const hourlyJob = cronius.createJob({ id: 'hourly-task', schedule: { every: 1, unit: 'hour', at: '9:00 AM' }, handler: async () => console.log('Hourly task executed'), }); // Run every week on Monday const weeklyJob = cronius.createJob({ id: 'weekly-task', schedule: { every: 1, unit: 'week', at: '9:00 AM' }, handler: async () => console.log('Weekly task executed'), }); ``` ### One-Time Execution ```typescript // Run once at a specific time const oneTimeJob = cronius.createJob({ id: 'one-time-task', schedule: new Date('2024-01-01T00:00:00Z'), handler: async () => console.log('One-time task executed'), }); ``` ### Job Dependencies ```typescript // Create jobs with dependencies const dataJob = cronius.createJob({ id: 'fetch-data', schedule: '0 * * * *', // Every hour handler: async () => { // Fetch data logic return { data: 'processed' }; }, }); const reportJob = cronius.createJob({ id: 'generate-report', schedule: '0 2 * * *', // Daily at 2 AM dependencies: ['fetch-data'], // Wait for data job to complete handler: async (job) => { // Generate report using data from fetch-data job return { report: 'generated' }; }, }); ``` ### Parallel Execution Groups ```typescript // Set up orchestrator for complex workflows const orchestrator = cronius.setupOrchestrator({ jobs: [dataJob, reportJob], parallelGroups: [ ['job1', 'job2'], // These jobs run in parallel ['job3', 'job4'], // These also run in parallel ], sequentialChains: [ ['group1', 'group2'], // group2 waits for group1 to complete ], }); // Execute parallel group await orchestrator.executeParallelGroup(0); ``` ### Event Handling ```typescript // Listen to job events const events = cronius.getEvents(); events.on('job-start', (event) => { console.log(`Job ${event.jobId} started at ${event.timestamp}`); }); events.on('job-success', (event) => { console.log(`Job ${event.jobId} completed successfully`); }); events.on('job-fail', (event) => { console.log(`Job ${event.jobId} failed:`, event.data?.error); }); events.on('job-retry', (event) => { console.log(`Job ${event.data.jobId} retrying (attempt ${event.data.attempt})`); }); ``` ### Error Handling and Retries ```typescript const resilientJob = cronius.createJob({ id: 'resilient-task', schedule: '*/5 * * * *', // Every 5 minutes handler: async (job) => { // Your task logic here if (Math.random() < 0.3) { throw new Error('Random failure'); } return 'success'; }, retryAttempts: 5, retryDelay: 1000, retryBackoff: 'exponential', onError: async (error, job) => { console.error(`Job ${job.id} failed after retries:`, error.message); // Send notification, log to external service, etc. }, onSuccess: async (result, job) => { console.log(`Job ${job.id} completed successfully:`, result); }, }); ``` ### Metrics and Monitoring ```typescript // Get system metrics const metrics = cronius.getMetrics(); const overallMetrics = metrics.getOverallMetrics(); console.log(`Total jobs: ${overallMetrics.totalJobs}`); console.log(`Success rate: ${overallMetrics.successRate.toFixed(2)}%`); console.log(`Average execution time: ${overallMetrics.averageExecutionTime}ms`); // Get job-specific metrics const jobMetrics = metrics.getJobMetrics('backup-database'); console.log(`Job executions: ${jobMetrics.executions}`); console.log(`Job failures: ${jobMetrics.failures}`); // Export Prometheus metrics const prometheusMetrics = metrics.getPrometheusMetrics(); console.log(prometheusMetrics); ``` ## CLI Usage Cronius includes a built-in command-line interface for job management: ```bash # List all jobs npx cronius list # Start a specific job npx cronius start backup-database # Stop a running job npx cronius stop backup-database # Show job status npx cronius status backup-database # Show system metrics npx cronius metrics # Create a demo job npx cronius create demo-job "0 * * * *" # Get help npx cronius help ``` ## Configuration Options ### Cronius Configuration ```typescript interface CroniusConfig { timezone?: string; // Default: 'UTC' maxConcurrentJobs?: number; // Default: 10 defaultRetryAttempts?: number; // Default: 3 defaultRetryDelay?: number; // Default: 1000ms retryBackoff?: 'linear' | 'exponential'; // Default: 'exponential' prometheusMetrics?: boolean; // Default: false logger?: Logger; // Custom logger implementation } ``` ### Job Configuration ```typescript interface JobConfig { id: string; // Required: Unique job identifier name?: string; // Optional: Human-readable name description?: string; // Optional: Job description schedule: string | Date | HumanSchedule; // Required: Execution schedule handler: JobHandler; // Required: Job execution function retryAttempts?: number; // Default: 3 retryDelay?: number; // Default: 1000ms retryBackoff?: 'linear' | 'exponential'; // Default: 'exponential' timeout?: number; // Optional: Execution timeout in ms dependencies?: string[]; // Optional: Job dependencies runCondition?: (job: Job) => boolean | Promise<boolean>; // Optional: Conditional execution onSuccess?: (result: any, job: Job) => void | Promise<void>; // Optional: Success callback onError?: (error: Error, job: Job) => void | Promise<void>; // Optional: Error callback metadata?: Record<string, any>; // Optional: Custom metadata } ``` ## Advanced Features ### Conditional Job Execution ```typescript const conditionalJob = cronius.createJob({ id: 'conditional-task', schedule: '0 * * * *', handler: async () => 'conditional execution', runCondition: async (job) => { // Only run if certain conditions are met const shouldRun = await checkSomeCondition(); return shouldRun; }, }); ``` ### Custom Logging ```typescript import winston from 'winston'; const logger = winston.createLogger({ level: 'info', format: winston.format.json(), transports: [new winston.transports.Console()], }); const cronius = new Cronius({ logger: { info: (message, meta) => logger.info(message, meta), warn: (message, meta) => logger.warn(message, meta), error: (message, meta) => logger.error(message, meta), debug: (message, meta) => logger.debug(message, meta), }, }); ``` ### Timezone Support ```typescript const cronius = new Cronius({ timezone: 'America/New_York', }); // All schedules will be interpreted in the specified timezone const eastCoastJob = cronius.createJob({ id: 'east-coast-job', schedule: '0 9 * * 1-5', // 9 AM Eastern, weekdays only handler: async () => console.log('East coast business hours'), }); ``` ## API Reference ### Core Classes - **Cronius**: Main orchestrator class - **Job**: Individual job instance - **Orchestrator**: Complex workflow management - **MetricsCollector**: Performance monitoring - **Scheduler**: Schedule parsing and calculation - **RetryManager**: Retry logic and backoff strategies ### Events - `job-start`: Job execution begins - `job-success`: Job completes successfully - `job-fail`: Job fails (before retries) - `job-retry`: Job retry attempt - `job-complete`: Job execution ends (any status) - `orchestration-start`: Workflow execution begins - `orchestration-complete`: Workflow execution ends - `orchestration-error`: Workflow execution error ## Contributing Contributions are welcome! Please read our contributing guidelines and ensure all tests pass before submitting a pull request. ## License MIT License - see [LICENSE](LICENSE) file for details. ## Support - **Issues**: [GitHub Issues](https://github.com/txkachi/cronius/issues) - **Documentation**: [GitHub Wiki](https://github.com/txkachi/cronius/wiki) - **Discussions**: [GitHub Discussions](https://github.com/txkachi/cronius/discussions) ## Changelog See [CHANGELOG.md](CHANGELOG.md) for a detailed history of changes.