node.jstypescriptscheduled-taskschron

Prevent the same job to run twice node-cron


I'm working with node and typescript, using node-cron 2.0 to schedule a background operation to run every hour.

  cron.schedule("0 0 * * * *", () => {
     purgeResponsesSurveys();
   });

I'm concerned about what happens if the method doesn't finish within 1 hour since I don't want two instances of my method to run at the same time.

What are the best practices to prevent the scheduler from invoking the function purgeResponsesSurveys if it is already running from the previous hourly invocation?


Solution

  • You can use a Semaphore to prevent parallel calls.

    You will need to know when purgeResponsesSurveys is done. So if it's asynchronous you will need to return Promise or receive a callback that will be called when purgeResponsesSurveys is done.

    I used semaphore npm package. Here is a small example/simulation.

    const semaphore = require('semaphore');
    
    const sem = semaphore(1);
    
    simulateCron(function() {
        console.log('cron was triggered')
    
        // wrap task with mutex
        sem.take(function() {
            longTask(function(){
                sem.leave();
            })
        })
    
    })
    
    function longTask(cb) {
        console.log("Start longTask")
        setTimeout(function(){
            cb()
            console.log("Done longTask")
        }, 3000)
    }
    
    function simulateCron(cb) {
        setInterval(cb, 500)
    }
    
    // output
    cron was triggered
    Start longTask
    cron was triggered
    cron was triggered
    cron was triggered
    cron was triggered
    cron was triggered
    Done longTask
    Start longTask
    cron was triggered
    ...