I have been working on a project which requires the start and stop of cron scheduler when a user clicks on a button on the front end. Basically when a user clicks on a button, the cron job will start. And clicking the stop button will stop the timer. It is as simple as that.
To achieve that, I am making post requests to the Nodejs/Express backend on button click which triggers start/stop function of the scheduler. This is how the endpoint looks like:
const cron = require('node-cron');
router.post('/scheduler', async (req, res) => {
// gets the id from the button
const id = req.body.id;
try{
// finds the scheduler data from the MongoDB
const scheduler = await Scheduler.find({ _id: id });
// checks whether there is a scheduler or not
if ( !scheduler ) {
return res.json({
error: 'No scheduler found.'
});
}
// creates the cronjob instance with startScheduler
const task = cron.schedule('*/10 * * * * *', () => {
console.log('test cronjob running every 10secs');
}, {
scheduled: false
});
// checks if the scheduler is already running or not. If it is then it stops the scheduler
if ( scheduler.isRunning ) {
// scheduler stopped
task.stop();
return res.json({
message: 'Scheduler stopped!'
});
}
// starts the scheduler
task.start();
res.json({
message: 'Scheduler started!'
});
}catch(e) {
console.log(e)
}
});
Right now the scheduler runs perfectly but it doesn't stop on second button click. It keeps on running. I feel like I'm not calling task.start()
and task.stop()
at correct places where it would work. And I don't know where the correct places are. I'm actually new to cronjobs.
It would be great if someone tells me what I am doing wrong.
Thanks in advance.
I have been working on a project which requires the start and stop of cron scheduler when a user clicks on a button on the front end. Basically when a user clicks on a button, the cron job will start. And clicking the stop button will stop the timer. It is as simple as that.
To achieve that, I am making post requests to the Nodejs/Express backend on button click which triggers start/stop function of the scheduler. This is how the endpoint looks like:
const cron = require('node-cron');
router.post('/scheduler', async (req, res) => {
// gets the id from the button
const id = req.body.id;
try{
// finds the scheduler data from the MongoDB
const scheduler = await Scheduler.find({ _id: id });
// checks whether there is a scheduler or not
if ( !scheduler ) {
return res.json({
error: 'No scheduler found.'
});
}
// creates the cronjob instance with startScheduler
const task = cron.schedule('*/10 * * * * *', () => {
console.log('test cronjob running every 10secs');
}, {
scheduled: false
});
// checks if the scheduler is already running or not. If it is then it stops the scheduler
if ( scheduler.isRunning ) {
// scheduler stopped
task.stop();
return res.json({
message: 'Scheduler stopped!'
});
}
// starts the scheduler
task.start();
res.json({
message: 'Scheduler started!'
});
}catch(e) {
console.log(e)
}
});
Right now the scheduler runs perfectly but it doesn't stop on second button click. It keeps on running. I feel like I'm not calling task.start()
and task.stop()
at correct places where it would work. And I don't know where the correct places are. I'm actually new to cronjobs.
It would be great if someone tells me what I am doing wrong.
Thanks in advance.
Share Improve this question edited Apr 7, 2021 at 17:05 Zak asked Apr 7, 2021 at 13:40 ZakZak 9404 gold badges22 silver badges45 bronze badges2 Answers
Reset to default 4 +50Every time you hit the scheduler api
a new instance of cron-job is made and you are stopping the newly defined instance of cron-job not the previous one.
Solution is to define the cron-job out of the scope of router so that whenever you hit the scheduler api
the instance won't change
Like this:
const cron = require('node-cron');
// creates the cronjob instance with startScheduler
const task = cron.schedule('*/10 * * * * *', () => {
console.log('test cronjob running every 10secs');
}, {
scheduled: false
});
router.post('/scheduler', async (req, res) => {
// gets the id from the button
const id = req.body.id;
try{
// finds the scheduler data from the MongoDB
const scheduler = await Scheduler.find({ _id: id });
// checks whether there is a scheduler or not
if ( !scheduler ) {
return res.json({
error: 'No scheduler found.'
});
}
// checks if the scheduler is already running or not. If it is then it stops the scheduler
if ( scheduler.isRunning ) {
// scheduler stopped
task.stop();
return res.json({
message: 'Scheduler stopped!'
});
}
// starts the scheduler
task.start();
res.json({
message: 'Scheduler started!'
});
}catch(e) {
console.log(e)
}
});
The problem might e from the line:
const task = cron.schedule('*/10 * * * * *', () => {
which, actually, creates a new task and uses a new Scheduler if you read the source code of node-cron: https://github./node-cron/node-cron/blob/fbc403930ab3165ffef7d53387a29af92670dfea/src/node-cron.js#L29
function schedule(expression, func, options) {
let task = createTask(expression, func, options);
storage.save(task);
return task;
}
(which, internally, uses: https://github./node-cron/node-cron/blob/fbc403930ab3165ffef7d53387a29af92670dfea/src/scheduled-task.js#L7:
let task = new Task(func);
let scheduler = new Scheduler(cronExpression, options.timezone, options.recoverMissedExecutions);
So, when you call:
task.stop();
As far as I understand, what you do is calling the method "stop" of a brand new task, not the method stop of the task you launched the first time you clicked the button.
Judging by your code, the problem is that you are not actually using your scheduler while using the task.
PS: The module also exposes a function that lets you retrieve tasks from its storage: https://github./node-cron/node-cron/blob/fbc403930ab3165ffef7d53387a29af92670dfea/src/node-cron.js#L58
But as I haven't found any documentation about it, I do not remend using it.