NPM cronJob - dynamically set time - node.js

here is my code for scheduling a task. i have used separate routes for starting,stopping and changing the time as given below. please tell me if its correct. and also im getting an error for changing the time frequency.please help me.
const cronjob=require('cron').CronJob
var first='* * * * * *'
var task=function() {
console.log('last'+job.lastDate()+' next '+job.nextDates(1));
}
var complete=function(){
console.log('the end.........')
}
var job = new cronjob(first,task, complete, false, 'Asia/Kolkata');
app.get('/start',(req,res)=>{
job.start()
console.log('is job running? ', job.running);
res.send('cron started')
})
app.get('/set',(req,res)=>{
var time=req.headers.time /* input taken from user for changing the frequency*/
time='30 5 1-31 0-11 1-7' /*hard-coded temporary for testing*/
console.log(time)
job.setTime(time)
})
/set api is throwing an error
/Error: time must be an instance of CronTime./

we have to use instance of a cronTime i.e.
const CronTime = require('cron').CronTime
.
.
.
var time=req.query.time
//time='*/5 * * * * *'
job.setTime(new CronTime(time))
res.send('time changes')

Related

Why custom services do not work on cron jobs in strapi.io

I created a cron job and use Strapi custom service that I wrote. But an error comes as: TypeError: Cannot read property 'services' of undefined at Job.1 * * * * * [as job] .
Here is my cron job code:
module.exports = {
'1 * * * * *': ({ strapi }) => {
strapi.services.account.myService();
},
};
I'm using strapi version 3.6.8.
The answer to this question is simple. You're using the syntax from StrapiV4 in StrapiV3. The correct syntax for cronjob in strapiv3 is as follows:
module.exports = {
/**
* Simple example.
* Every monday at 1am.
*/
'0 0 1 * * 1': () => {
// you can then reference you strapi custom service like so
await strapi.services.account.myServiceMethod();
},
};
References
Cron Jobs in Strapi V4
Cron Job in Strapi V3

NodeJS Dynamic Service Loader & Runner

Context:
I'm trying to build a few slack hooks / notification services for a channel I'm active on, being the cheap-skate finance savvy person that I am, I'd like to make use of a free service as such (trail Heroku accounts, or similar products), thus I'd like to be able to run multiple services on a single instance.
I've created a generic runner, that should be based on a config and be able to pick up some node modules and supply them the config settings.
I'm using the following node_modules:
"auto-loader": "^0.2.0",
"node-cron": "^1.2.0",
"read-yaml": "^1.1.0"
config.yml
foo:
cron: 1 * * * *
url: http://www.foo.com
team:
-
slackId: bar
bnetId: 1
eloId: 1
-
slackId: baz
bnetId: 2
eloId: 2
app.js
const autoLoader = require('auto-loader');
const readYaml = require('read-yaml');
const cron = require('node-cron');
const services = autoLoader.load(__dirname +'/services')
readYaml('config.yml', function(err, conf) {
if (err) throw err;
Object.keys(conf).forEach(function (key) {
console.log('Creating CRON for ' + key);
if(cron.validate(conf[key].cron)) {
console.log(conf[key].cron, '-> is valid cron');
// the cron task below does not seem to fire ever
cron.schedule(conf[key].cron, function(){
services[key](conf[key]);
});
} else {
console.log('Cron invalid for::' + key)
}
});
});
service/foo.js
module.exports = function (config) {
console.log('foo entered!!');
console.log(config)
}
Question:
What am I missing? If I remove the cron schedule, my services get hit, thus my assumptions are as follows...
Either I'm missing something conceptually about how long running process are meant to work in NodeJS (as this is my first), or I'm missing a super (not obvious) to me bug.
How do you create a long running task/process in NodeJS with separate scheduled code sections / tasks?
The code itself works as expected. The issue appears to be with the configuration of the cron.
cron: 1 * * * * will run at 1 minute past the hour.
cron: "*/1 * * * *" # would run it every minute
cron: "*/5 * * * *" # would run it every 5 minutes
cron: "*/10 * * * * *" # would run every 10 seconds

How to convert general time to cronjob time using nodejs?

A cronjob time syntax such as "* * * * * *" followed cron npm
I want convert time from "2017-05-09T01:30:00.123Z" to cron job time format. Have library or method can implement it?
const dateToCron = (date) => {
const minutes = date.getMinutes();
const hours = date.getHours();
const days = date.getDate();
const months = date.getMonth() + 1;
const dayOfWeek = date.getDay();
return `${minutes} ${hours} ${days} ${months} ${dayOfWeek}`;
};
const dateText = '2017-05-09T01:30:00.123Z';
const date = new Date(dateText);
const cron = dateToCron(date);
console.log(cron); //30 5 9 5 2
FYI, you've mentioned "* * * * * *" as a syntax/format of cron which is incorrect. The correct format consists of 5 values separated with spaces (instead of 6 values).
I don't know if there is any library for it or not. But you can simply implement it using simple date functions.
var date=new Date("2017-05-09T01:30:00.123Z");
var mins=date.getMinutes();
//mins variable for the 1st * and so on
var secs=date.getSeconds();
var dayofmonth=date.getDate();
var month=date.getMonth();
var dayofweek=date.getDay();
You can then build a string and use those values in the cron module.

How to create application level variable in node.js

In my project I have running more than 100 cron jon using npm cron. My problem is I need to stop any cron job at run time.
my code is
in app.js file
var cronJobRunner =require('cronJobHandle.js');
global.jobManager = {};
cronJobRunner.startServiceFromCronJobManager("service 1")
in cronJobHandle.js
var CronJob = require('cron').CronJob;
module.exports = {
startServiceFromCronJobManager: function (scheduleServiceName) {
var serviceList =['service1','service2','service3','service4']
serviceList.forEach(function(service){
var job = new CronJob('* * * * * *', function(){
console.log("Service running");
}, function () {
// This function is executed when the job stops
},
true /* Start the job right now */,
timeZone /* Time zone of this job. */
);
global.jobManager.service = job;
});
},
stopServiceFromCronJobManager: function (scheduleServiceName) {
console.log(global.jobManager);
global.jobManager[scheduleServiceName].stop();
}
};
router.js
var cronJobRunner =require('cronJobHandle.js');
app.route('/stopservice',function(req,res){
cronJobRunner.stopServiceFromCronJobManager("service1");
}
When I call http://localhost:9999/stopservice
I am getting undefine in console.log(global.jobManager);
Please help me how to maintain cron jobManager variable comman for all server side js files
It is global but there's two bugs in your code.
1) you're calling the property called "service" instead of the one whose name is in service.
Change
global.jobManager.service = job;
to
global.jobManager[service] = job;
2) you're pottentially using global.jobManager in cronJobHandle.js before to declare it in app.js
There's a better solution. you don't need and should use global. Just declare a standard variable in cronJobHandle.js instead (so that it isn't accessed by other modules):
var jobManager = {};
...
jobManager[service] = job;
...
jobManager[scheduleServiceName].stop();

How do invoke script with another node script?

I have an node app that runs as a cron job every few seconds:
var CronJob = require('cron').CronJob;
new CronJob('*/5 * * * * *', function(){
console.log('Here invoke a script called requestdata');
}, null, true, "America/Los_Angeles");
and I just want to call a script without invoking functions on it. So its not
requestdata.foo();
but just call requestdata in same directory. how is this done? If it was on command line I would just do:
node requestdata
but how do I do this inside another script?
Use child_process, like so
var cp = require('child_process');
cp.fork(__dirname + '/request data.js');
See http://nodejs.org/api/child_process.html
This solution also shows how to pass parameters to the "request data.js" script
var cp = require('child_process');
cp.fork(__dirname + '/request data.js',[array,of,string,prams]);

Resources