0

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?

s.demuro
  • 399
  • 2
  • 15

1 Answers1

1

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
...
Daniel
  • 2,288
  • 1
  • 14
  • 22
  • thank you for the answer! I'm wondering how did you decide to use semaphore(1) over mutex? – s.demuro Feb 21 '22 at 13:35
  • `semaphore(1) == mutex` when using this lib. But as long as you have some kind of Lock set to 1 you will be OK. – Daniel Feb 21 '22 at 13:56
  • Does it work also if the application is deployed in a cluster? – s.demuro Feb 21 '22 at 14:04
  • In principle, you should have only *one* instance of this application running. If you have many many tasks on one npm possess can't handle them I would suggest using Redis or Queue lib to delegate the semaphore to. – Daniel Feb 21 '22 at 14:17