So, I found an old question about this (here: How to stop a node cron job) but it doesn't work for me (and I can't realize the reason why).
I'm using cron-job-manager (since I plan to use more than one scheduled job at the same time) but as far as I know it should be built on node-cron (but I'm a newbie, so...)
So, I'm asking again: how do I deal with starting and stopping a cron job under certain conditions?
I'm actually doing this for a discord bot: basically, the user input a command for starting and one for stopping.
First try was something like:
job = cron('keyTask','* * * * * *', ()=>{
//Do the actual job
},
{
start: false,
timeZone:"Europe/London",
});
switch args[1]
case go:
job.start();
break;
case stop:
job.stop();
break;
This start the job successfully when the user gives the 'go' command, but when it gives the 'stop' command, the scheduled job just won't stop.
Second try is:
var x = args [1];
new cron('keyTask' , '* * * * * *', job(doTheThing(x)) ,
{
start: false,
timeZone:"Europe/London",
});
Where job() is a function defined beforehand that contains the actual job and DoTheThing() is something that gives true or false depending on what the user is saying in input.
This executes the scheduled job once and then stops.
Somehow I suspect that the issue here is related to the fact that I'm defining function externally, while in most examples I saw the function is always written within the cron().
So, I'm out of ideas: thanks in advance for any help!
Related
I would like to do some cronjob using the Node.js package "cron" every 10 minutes.
This cronjob takes between 5 to 15 minutes, and I don't want that in a case that one instance is still running - another will be joining it in parallel. Instead, it will skip the additional running and wait until the next period.
Is it possible to implement it using this package?
Here is the code of the implementation using the cron package :
const CronJob = require("cron").CronJob;
const job = new CronJob(
'0 */10 * * * *',
()=>SomeCronJob(),
null,
true,
'America/Los_Angeles',
);
I thought of implementing it using a combination of simple setInterval() and clearInterval() instead of the package, not sure how though.
I'd appreciate any help!
I would use a flag to check if the job is running. Example:
let isJobRunning = false;
function SomeCronJob() {
if (isJobRunning) {
// Skip
return;
}
isJobRunning = true;
// run stuff
// Once is finished
isJobRunning = false;
}
I have node application in which I want to run tasks on daily basis. So I want to use node-cron to schedule tasks but not like this:
var cron = require('node-cron');
cron.schedule('* * * * *', function(){
console.log('running a task every minute');
});
I need some generic solution so that at one place I have just empty body for cron job that takes different functions from a different location. That means in total we have two files, one which has just cron job function handler and other have a list of cron jobs. From where we want to run these jobs we just need require and some basic calling.
Can anyone suggest me this solution?
I got my solution. Using node-cron-job module I have achieved what I wanted. Let me explain in detail:-
First i created new file which contains jobs, lets name it jobs.js :-
// jobs.js
exports.first_job = {
on:"* * * * * " //runs every minute
},
job: function () {
console.log("first_job");
},
spawn: true
}
exports.second_job = {
on: "*/2 * * * * *", //runs every 2 second
job: function () {
console.log("second_job");
},
spawn: false // If false, the job will not run in a separate process.
}
Here, we define two jobs name first_job and second_job. We can define as many required.
Finally, we need to call these jobs from any location by these simple steps:-
// main.js
var cronjob = require('node-cron-job');
cronjob.setJobsPath(__dirname + '/jobs.js'); // Absolute path to the jobs module.
cronjob.startJob('first_job');
cronjob.startJob('second_job');
We can call all jobs in a single call like this:-
cronjob.startAllJobs();
I am running a cron job using the module node-cron for node js . My code is below.
var Job = new CronJob({
cronTime: '* * 01 * * *', //Execute at 1 am every day
onTick : function() {
co(function*() {
yield insertToDatabase(); //this is the function that does insert operation
}).catch(ex => {
console.log('error')
});
},
start : false,
timeZone: 'Asia/Kolkata'
});
I need to execute this only one time but this cronjob once starts runs multiple times due to which same data gets inserted to my database. I only need to run this job only one time. What should i do.
I know I am late to the party but I think that I have a solution. I hope this can help someone else in the future (Hi future!)
I encountered what I think to be the same issue as the asker, that is, the OnTick function executes multiple times after the scheduled time, this appeared to the author to be an endless loop. The asker expected this function to run only once at the scheduled time everyday (today, tomorrow, etc).
With that in mind the cause of this "issue" is simple. The cron job is scheduled to to exactly this. The cron time entered is * * 01 * * * which means the hour is 01 (aka 1:00am) but the minutes and seconds are *. This means any minute and any second where the hour is 01. So this will run from 1:00am up until 1:59am. It will run for each second of each minute until 2:00am. If the author had waited until 2:00am the "looping" would have ceased.
The solution is to set the seconds and minutes to anything that is not * (0 in my case worked).
I feel really silly for not having figured this out right away but here it is!
You can call Job.stop() from onTick:
onTick : function() {
Job.stop();
co(function*() {
yield insertToDatabase();
}).catch(ex => {
console.log('error');
});
}
In my case, i changed my code from this :
var job = new CronJob('*/59 * * * *', onTick, onComplete, true, 'Asia/Kolkata'); // onTick and onComplete is a function, which i'm not showing here
job.start();
To this :
var job = new CronJob('*/59 * * * *', onTick, onComplete, false, 'Asia/Kolkata'); // onTick and onComplete is a function, which i'm not showing here
job.start();
Thanks
So, I've got some js code which is a slackbot which supposed to simply listen and parse the date provided, then start a CronJob to run a certain function according to the cron or date format provided. Something like this.
var CronJob = require ('cron').CronJob;
...
robot.respond(date, function (msg)) {
if(!isValidDate(date)) msg.reply("not a valid date);
var interval = isCronDate(date) ? date : new Date(date);
msg.reply("Job about to be scheduled.")
var schedule = new CronJob(interval, processDataOnDate(), function() { msg.reply("hello") }, true);
}
I've got a coffee file testing this code, and I expect certain responses back, but I do NOT expect the cron job to be executed based on the date I've provided in my test code. However, it is. Is this normal? Does mocha force the code to finish execution due to the fact that this is a unit test, or am I doing something wrong? I am running this to execute my unit test.
mocha --compilers coffee:coffee-script/register
For further information I am running this as a slackbot, so this is all done in the form of 'say' and 'reply.' One of my tests looks like this.
beforeEach ->
yield #room.user.say 'bob', '#bot schedule at 2017-05-25 18:00:00'
expect(#room.messages).to.eql [
['bob', 'bot schedule at 2017-05-25 18:00:00']
['bot', 'Job about to be scheduled']
]
The test fails and informs me that the actual result included the message 'hello' from the bot, despite the fact that the date I've provided in my test is in the future.
The last parameter when you're initializing your CronJob indicates that it should execute the job immediately:
new CronJob(interval, processDataOnDate(), function() { msg.reply("hello") }, true);
That will cause the job to execute immediately, even though your execution date is in the future.
See: https://www.npmjs.com/package/cron#api
I am new to Agenda jobs (https://github.com/rschmukler/agenda) and fail to understand how I can schedule a job to run every day at a given time. I have tried the following:
agenda.every('everyday at 00:01', ...) - runs only one time.
agenda.schedule('at 00:01', ...) and then job.repeatEvery('1 day') but without much effect.
Agenda internally uses Human Interval which is inspired by date. i checked demo of date here and found that everyday at 00:00 is accepted but could not use that very well with Agenda.
Any help will be appreciated. Thank you.
//You can use something like this...
agenda.define('first', (job, done) => {
Somefunction()
job.repeatEvery('24 hours', {
skipImmediate: true
});
job.save()
done()
})
agenda.start()
agenda.on('ready', function () {
agenda.schedule('everyday at 00:00','first')
})
// This worked for me..
I think you can use repeatAt() for this purpose. Like repeatAt('12am')
or you can also use 24 hour format:- repeatAt('00:00')
The solution proposed by others, I think is a bit funky as calling job.repeatEvery() within the job handler feels kind of out of its place.
agenda.every accepts cron format, therefore you can apply it to any defined job and run the handler according to the cron sequence
You have a defined job:
agenda.define('do-something', async (job, done) => {
// Doing some heavy async stuff here
async heavyStuff();
done();
})
After server initialisation you can call it anywhere in your code to setup a repeated job. Just make sure await agenda.start() was already called and agenda has an established mongo connection
await agenda.every("0 1 * * *", "do-something");
This will run the do-something job and call the handler every day at 00:01am