I was trying to run an API call at a scheduled time. I researched through sites and found this package called node-schedule from npmjs. This is working as expected by calling the code at required time. The issue I am having is :
Suppose I have a list of times eg: ["10:00","11:00","13:00"]
Once I start the server, it will get executed at required times. But what if I want to change the time list dynamically?
Exactly what I am trying to do:
What I want: Dynamically add this newly added time to the cron-schedule
index.js
const express = require('express');
const schedule = require('node-schedule');
const app = express();
const port = 5000;
var date = new Date(2019, 5, 04, 14, 05, 20);// API call here
var j = schedule.scheduleJob(date, function(){
console.log('The world is going to end today.');
});
app.get('/test', (req, res) => {
var date = new Date(2019, 5, 04, 14, 11, 0); // Will call API here
var q = schedule.scheduleJob(date, function(){
console.log('Hurray!!');
});
res.send('hello there');
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
The code written above is what I have and its pretty messed up. What I am conveying there is that, while running the index.js
file API is called and the cron-schedule
gets executed. Now if there is some new values added to DB I want to rerun this.
Rerunning index.js
is another option I have, but I don't think its the right thing to do. The next option I have in mind is to call another endpoint which is mentioned as /test
above, which would eventually run the cron again.
Please let me know some suggestions or some sort of solution to this so I can rectify my mistakes.
With this code I think you could do what you want, although you must adapt it to your needs in terms of defining the functions that will execute the tasks or if you need to specify the times in which they will be executed in another way (setting specific days of the week, for example).
var times = [];
var tasks = [];
function addTask(time, fn) {
var timeArr = time.split(':');
var cronString = timeArr[1] + ' ' + timeArr[0] + ' * * *';
// according to https://github.com/node-schedule/node-schedule#cron-style-scheduling
var newTask = schedule.scheduleJob(cronString, fn);
// check if there was a task defined for this time and overwrite it
// this code would not allow inserting two tasks that are executed at the same time
var idx = times.indexOf(time);
if (idx > -1) tasks[idx] = newTask;
else {
times.push(time);
tasks.push(newTask);
}
}
function cancelTask(time) {
// https://github.com/node-schedule/node-schedule#jobcancelreschedule
var idx = times.indexOf(time);
if (idx > -1) {
tasks[idx].cancel();
tasks.splice(idx, 1);
times.splice(idx, 1);
}
}
function init(tasks) {
for (var i in tasks){
addTask(i, tasks[i]);
}
}
init({
"10:00": function(){ console.log("It's 10:00"); },
"11:00": function(){ console.log("It's 11:00"); },
"13:00": function(){ console.log("It's 13:00"); }
});
app.post('/addTask', (req, res) => {
if (!req.body.time.match(/^(0[0-9]|1[0-9]|2[0-3]|[0-9]):[0-5][0-9]$/)) {
// regex from https://stackoverflow.com/a/7536768/8296184
return res.status(400).json({'success': false, 'code': 'ERR_TIME'});
}
function fn() {
// I suppose you will not use this feature just to do console.logs
// and not sure how you plan to do the logic to create new tasks
console.log("It's " + req.body.time);
}
addTask(req.body.time, fn);
res.status(200).json({'success': true});
});