Schedule Repeatable Jobs using bull.js By providing time in repeat rules - node.js

I'm currently using bull js to create an api that schedules a job according to inputted time. currently I'm able to do this using crone expression if the time input is in the format of 'YYYY-MM-DD HH:mm". The only problem is that if I want to schedule a job that will run daily I have to write some logic to get time from the inputed time. My question is whether I can specify the repeat rules using a date input as it is done in node-schedule. in short, am looking for the equivalent of the following node-schedule implementation in bull.
var date = new Date(2012, 11, 21, 5, 30, 0);
var j = schedule.scheduleJob(date, function(y){
console.log(y);
}.bind(null,x));```

Based on the documentation, repeating tasks/jobs are handled using cron syntax:
paymentsQueue.process(function(job) {
// Check payments
});
// Repeat payment job once every day at 3:15 (am)
paymentsQueue.add(paymentsData, { repeat: { cron: "15 3 * * *" } });
Use this cron expression validator to verify your logic is correct.

Related

Dynamic cron parameters _ Node Js

I have a script that send an email to specific customer but what I'm trying to do is to fire that email in a given time and date .. so the solution is to use cron module like below and changing the parameters with what I want
cron.schedule("* * * * * " , function(){
}
the problem that I want to modify those parameters with varibales which contains a result for a specific calculation! like this below
const X = 234;// this values will change everyday automatically
cron.schedule("X * * * * " , function(){
}
so is it possible to do something like that or is there a better solution that allows me to modify cron parameters
the solution that I tried but nothing is working is below :
const x = 40;// 40 seconds
cron.schedule(`${x} * * * *`, function(){
}
Best Regards,
Many Thanks to num8er ,
the only solution for my problem is
Simply save to table jobs the stuff need to do and put cron script to run every minute which will check jobs table and will run what is scheduled by time. Example table: jobs [id, runAt, method, arguments, done], cron will run and will take jobs which is not done and runAtis less than now, will run method and pass arguments to it and after finishing it will set done=true
that's enough simple to achieve: 1 insert to table, 1 method that will run by cron and get jobs from table and execute

How To Run Node-Schedule Task Every 15 Days In Nodejs?

I'm using Node-Schedule package and I'm having some trouble to define the criteria using the * system.
Does anyone know how can I run this task every day 15 and 30 of a month (15 days interval)
var schedule = require('node-schedule');
var tarefa = schedule.scheduleJob('15-30 * * ', function() {
console.log("TAREFA");
});
One more question, let's say I wanna change this later based on user selected option, how can I get this current task schedule and change this interval later?
Thanks in advance!
0 0 0 1,15 * ? should work (see Quartz Cron expression :Run every 15 days ie twice in a month).
To change the schedule, you can call the rescheduleJob method with the job's name and the new user-specified schedule.
var schedule = require('node-schedule')
schedule.scheduleJob('myJob', '0 0 0 1,15 ? *', function() { console.log('hi') } )
schedule.rescheduleJob('myJob', '0 0 0 1,20 ? *')

NodeJS - Schedule a very simple task to run at a certain datetime

I am implementing a booking system, and I need to record the concept of the time between the job being accepted and the job starting, and then the duration of the job. I need to move from 'State A' to 'State B' when the start time of the job is reached, and then from 'State B' to 'State C' once the end time of the job has been reached.
I know I could implement this using a queue system like Bull or Bee-Queue, but it seems wrong, as I only need to change the 'State' of my job, not perform any background processing.
How can I simply say "At 3pm, change this Task to 'State B', and at 5pm, change this Task to 'State C'".
Could I poll my DB every minute? Is this the 'correct' approach?
How about using node-cron module? You can use node-cron to schedule jobs based on time, frequency etc. see the official link for more examples
https://www.npmjs.com/package/node-cron
I pasted one for reference
var cron = require('node-cron');
cron.schedule('* * * * *', function(){
console.log('running a task every minute');
});
An approach that doesn't involve scheduling would be to have the value of your state property calculated at request time.
Instead of updating the value of state at exactly 3pm, you check the current time when someone requests the booking resource. If it's >3pm and <5pm return the state as 'State B'. If its >5pm, return state as 'State C'.
You can use setTimeout(function, timeout) to schedule task at certain period of time.
var now = new Date(); //creates date object at current time
var date = new Date(...); //create first state-changing time
//Execute task after (date - now) milliseconds
setTimeout(function(){
//execute tasks
}, date - now);
Now you can do setTimeout() inside setTimeout() with the help of loops to complete your task!

What to check in my quartz.net job dispatcher for timezone funkyness

Using Quartz.net Server version 2.1.2 which I upgraded to from version 2.0 because of a lack of support for UTC timezone offsets. Jobs are not being sent at the time we specify, and it is seemingly because of timezone offsets.
I have three job types:
Job Frequency Requirments
Daily (once a day at a given time)
Weekly (on one to N days, once each day at a given time)
Monthly (on one to n days, once a day, or at the last day)
For all three I use Cron expressions with SimpleTriggers.
My question is:
what are the things I need to tick off to verify that the jobs I am scheduling, and the jobs that are going to run on the server, will run on time in their timezone?
It appears that simply specifying the timezone is not enough; I specify the timezone like this
dailyTrigger.TimeZone = BrainTimeZone;
but on the server that holds the quartz instance (in PST) gets a job scheduled for 2:00pm in NYC (EST), the "Next Run Time" should be 2:00pm, but it shows and runs at noon.
Here are a few excellent s/o articles on Quartz Time Zones:
Quartz.net UTC Resources:
Quartz.NET - Using/understanding cron based trigger and time zone/summertime (daylight saving time)
What time am I dealing with in Quartz.net?
Quartz .NET MakeDailyTrigger
Here is how I currently schedule a daily:
private void CreateDaily()
{
var expression = CronScheduleBuilder
.DailyAtHourAndMinute(GetNormalizedHour(), Minute)
.InTimeZone(TimeZone)
.Build() as CronTriggerImpl;
IJobExecutionContext jobContext = GetJobContext();
IJobDetail job = JobBuilder.Create<MailJob>()
.WithIdentity(JobName, GroupName)
.UsingJobData(jobContext.JobDetail.JobDataMap)
.Build();
ScheduleBuilder<>cronExpressionString
var cronExpressionString = expression.CronExpressionString; // returns a cron expr.
var dailyTrigger = (ICronTrigger)TriggerBuilder.Create()
.WithIdentity(JobName, GroupName)
.WithSchedule(cronExpressionString)
.Build();
dailyTrigger.TimeZone = BrainTimeZone;
this.JobTrigger = dailyTrigger;
this.JobDetail = job;
this.Success = true;
}
I tried to use a DailyTimeIntervalTriggerImpl, but this does not seem like the right trigger for any of those 3 above interval types.
private void DailyJob()
{
#region Duration
var daysOfWeek = new Quartz.Collection.HashSet<System.DayOfWeek>
{
System.DayOfWeek.Monday,
System.DayOfWeek.Tuesday,
System.DayOfWeek.Wednesday,
System.DayOfWeek.Thursday,
System.DayOfWeek.Friday,
System.DayOfWeek.Saturday,
System.DayOfWeek.Sunday,
};
DateTimeOffset startTime = DateTime.Now;
DateTimeOffset endTime = DateTime.Now.AddYears(1);
TimeOfDay startTimeOfDay = TimeOfDay.HourMinuteAndSecondOfDay(Hour, Minute, 0);
TimeOfDay endTimeOfDay = TimeOfDay.HourMinuteAndSecondOfDay(Hour, Minute, 30);
#endregion
IJobExecutionContext jobContext = GetJobContext();
if (JobName == null || GroupName == null) {
this.Success = false;
return;
}
var dailyTrigger = new DailyTimeIntervalTriggerImpl
{
StartTimeUtc = startTime.ToUniversalTime(),
EndTimeUtc = endTime.ToUniversalTime(),
StartTimeOfDay = startTimeOfDay,
EndTimeOfDay = endTimeOfDay,
RepeatIntervalUnit = IntervalUnit.Week,
DaysOfWeek = daysOfWeek,
// RepeatInterval = 1,
TimeZone = TimeZone,
Key = new TriggerKey(JobName, GroupName),
};
// Compute fire times just to show simulated fire times
IList<DateTimeOffset> fireTimes = TriggerUtils.ComputeFireTimes(dailyTrigger, null, 1000);
foreach (var dateTimeOffset in fireTimes)
{
QuartzLog("Daily trigger has been computed - fireTimes as follows:\r\n\r\n");
QuartzLog(string.Format("utc:{0} - adjusted time:{1} - timezone:{2}", dateTimeOffset,
TimeZoneInfo.ConvertTimeFromUtc(dateTimeOffset.DateTime, BrainTimeZone), BrainTimeZone.DisplayName));
}
I am in the process of refactoring all my quartz layers, so I am looking for best practices and a bullet proof method of assuring that jobs will run at the times we specify, regardless of where the Quartz.net job server is located, and where the user's time zone originated from and where they want it to end up arriving at.
We are moving our quartz.net servers to AWS so we will have a distributed server farm to host these with timezones that can change.
How can I set up my quartz architecture so that it is dynamic enough and as I stated above, bullet proof, in sending jobs on time - regardless of TimeZones / Offsets / DaylightSavings / LeapYear / Sleat / Snow / Rain / Zombie Attacks / Y2K / Meteoric ELE / etc. ?
Thank you.

Issue in timezone with Node.js Module 'time'

I just came across an issue that has happened today (due to being 31st of January here in Australia Sydney). Basically, given a year,date,hour,minute,second. I want to create a date as if I am in a timezone (Australia/Sydney) and then convert it to UTC (i.e. getting the milliseconds).
This is done due to the fact that the database (and the server) works in UTC, where as the client can be in any given timezone (when a post request is done, the client provides both the timezone and the year,month,date,hour,minute,second values)
The problem is, that when I am creating a date for today, its throwing off the date all the way back to January the 3rd of this month, here is the code that illustrates the problem
var scheduled, someTime, time, timeinfo, timezone;
process.env.TZ = 'UTC';
time = require('time');
timeinfo = {
hour: 14,
minute: '47',
year: 2013,
month: 1,
date: 31
};
timezone = 'Australia/Sydney';
someTime = new Date(timeinfo.year, timeinfo.month - 1, timeinfo.date, timeinfo.hour, timeinfo.minute, 1, 1);
scheduled = time.Date(timeinfo.year, timeinfo.month - 1, timeinfo.date, timeinfo.hour, timeinfo.minute, 1, 1, timezone);
console.log(someTime);
console.log(scheduled);
When you run this in Node.js, the time outputted by console.log(scheduled); is completely off.
Note: I am using the time npm library.
Seems to be a bug with how node-time calculates timezones, related to the order of the operations when doing the transform. There's an open issue (#28) on github.com as of now.
I have submitted a pull request, try that in the mean-time and see if it works for your particular case.
Please try the following codes
1.For GMT Time
var GMTtimeObj = new Date();
2.For UTC Time:
var UTCtimeObj = +new Date();
Let me know does it works for your requirement.
Go through this post's answers as well it might help you..
This was a bug that was fixed recently, please look at https://github.com/TooTallNate/node-time/pull/30
Its working perfectly now

Resources