javascript Utilities

Cron Job Manager

Node.js cron job manager with job registration, error handling, execution logging, and graceful shutdown.

Apex Logic 0 copies
javascript
const cron = require('node-cron');

class CronManager {
    constructor() {
        this.jobs = new Map();
        this.logs = [];
    }

    register(name, schedule, handler, options = {}) {
        if (this.jobs.has(name)) {
            console.warn(`Cron job '${name}' already registered. Skipping.`);
            return this;
        }

        const { timezone, runOnInit = false, enabled = true } = options;

        if (!cron.validate(schedule)) {
            throw new Error(`Invalid cron schedule for '${name}': ${schedule}`);
        }

        const wrappedHandler = async () => {
            const start = Date.now();
            const logEntry = { name, startedAt: new Date(), status: 'running' };

            try {
                console.log(`[CRON] Running: ${name}`);
                await handler();
                logEntry.status = 'success';
                logEntry.duration = Date.now() - start;
                console.log(`[CRON] Completed: ${name} (${logEntry.duration}ms)`);
            } catch (err) {
                logEntry.status = 'failed';
                logEntry.error = err.message;
                logEntry.duration = Date.now() - start;
                console.error(`[CRON] Failed: ${name} -`, err.message);
            }

            this.logs.push(logEntry);
            if (this.logs.length > 1000) this.logs.shift();
        };

        const task = cron.schedule(schedule, wrappedHandler, {
            scheduled: enabled,
            timezone,
        });

        this.jobs.set(name, { task, schedule, handler: wrappedHandler, options });

        if (runOnInit) wrappedHandler();

        console.log(`[CRON] Registered: ${name} (${schedule})`);
        return this;
    }

    start(name) {
        const job = this.jobs.get(name);
        if (job) job.task.start();
        return this;
    }

    stop(name) {
        const job = this.jobs.get(name);
        if (job) job.task.stop();
        return this;
    }

    stopAll() {
        for (const [name, { task }] of this.jobs) {
            task.stop();
            console.log(`[CRON] Stopped: ${name}`);
        }
    }

    getStatus() {
        const status = {};
        for (const [name, { schedule }] of this.jobs) {
            const lastLog = [...this.logs].reverse().find(l => l.name === name);
            status[name] = { schedule, lastRun: lastLog || null };
        }
        return status;
    }

    getLogs(name, limit = 50) {
        const filtered = name ? this.logs.filter(l => l.name === name) : this.logs;
        return filtered.slice(-limit);
    }
}

module.exports = new CronManager();

Tags

cron scheduler node-cron automation

Related Snippets

javascript

JWT Authentication Middleware

javascript

MongoDB Connection with Retry

javascript

Express Global Error Handler

javascript

Rate Limiter with Sliding Window