Quartz scheduler incorrect schedule time - java

I have a spring boot application in which I am trying to schedule a job using quartz scheduler to run daily at a specific time of the day. The following is my code to build the trigger.
DailyTimeIntervalScheduleBuilder scheduleBuilder = DailyTimeIntervalScheduleBuilder
.dailyTimeIntervalSchedule()
.startingDailyAt(TimeOfDay.hourAndMinuteFromDate(activeStartTime))
.endingDailyAfterCount(1)
.withMisfireHandlingInstructionFireAndProceed();
MutableTrigger trigger = scheduleBuilder.build();
The problem I am facing is that the job is scheduled but starting from the next day. So for instance, if I schedule the job for May 22 16:45, then the first fire time for the job is set to May 23 16:45.
I have tried using the builder with withIntervalInHours(24) instead of endingDailyAfterCount(1), but the result is the same.
I am not sure what seems to be the problem.
Note: This behavior is the same regardless of when I schedule my job, i.e., it doesn't matter if I execute this code before or after 16:45, the job is always scheduled for the next day
I am using spring boot version 1.5.10 and spring-boot-starter-quartz version 2.2.5.RELEASE

Can you try below code
CalendarIntervalScheduleBuilder schedule = CalendarIntervalScheduleBuilder
.calendarIntervalSchedule()
.inTimeZone(TimeZone.getDefault())
.withIntervalInDays((int) 1)
.withMisfireHandlingInstructionFireAndProceed();
Trigger trigger = TriggerBuilder
.newTrigger()
.startAt(startDateTime)
.withSchedule(schedule).build();
For the field startDateTime please use current Date time. if you want to start from May 22 16:45 then create the Date object accordingly.
And set the timezone also, or it will pick default system's timezone.

Related

Spring #Scheduled cron job in combination with Instant.now()

In Spring I use standard CRON job scheduling to do some business level measurements every 10 minutes with this example
#Async
#Scheduled(cron = "0 0/10 * * * ?")
public void takeMeasurements() {
Instant dateTimeNow = Instant.now();
// Business impl of measurements taking & storing into DB
}
I've had no problem with this impl in under multiple customer environments (Win, MacOS, Linux) running as SpringBoot containers in docker but I observed that in one Win10 Enterprise environment the timestamp coming from Instant.now() called when CRON job fires has time "in past" e.g. 11:59:59:998 with job that was supposed to be fired at 12:00:00.
I can handle this scenario with some accepted range of deviation (for my purposes it's OK to do "rounding" of +-30s) but for some folks/scenarios it might not be.
Where is the underlying problem of this?
Doesn't CRON use same machine clock as java.time.Instant uses?

I'm having a problem with #Scheduled and spring boot. A job after finished happens to run again sometimes after some minutes

I'm having a problem with #Scheduled and spring boot in a job that have to be executed each hour in the day, but the job is being executed when he shouldn't.
For instance... The job has to be executed each hour 00:00:00:000, 01:00:00:000, 02:00:00:000 and so on ... but sometimes, it's not a pattern, happens to be executed again after some minutes for another pod on k8s. Cronjob time is (0 0 * * * ?) every hour.
lock settings
defaultLockAtMostFor = "PT40S",
defaultLockAtLeastFor = "PT20S"
job executation logs
There's a scheduller table in the DB to control the lock, to avoid two pods to execute at the same cronjob time.
anyone knows why this kind of behaviour happens?
Thanks in advance!

Quartz Scheduler getFinalFireTime null even with an expired cron

I'm using Quartz Scheduler in Java to schedule jobs based on entries in a database. I'm trying to automate disabling those entries when they will never run again, so I don't try to read them every time the application starts.
I have a cron for a very specific date, for example 0 25 12 4 DEC ? 2021. That is a specific date, it has passed, and cannot ever fire again.
I build a chrontrigger and check endTrigger.getFinalFireTime() and it returns null, which I believe should only happen when the cron allows future firing.
// Build the end cron trigger
CronTrigger endTrigger = TriggerBuilder.newTrigger()
.withIdentity("eventEndCron", "quartzGroup")
.withSchedule(CronScheduleBuilder.cronSchedule("0 25 12 4 DEC ? 2021"))
.forJob("eventEnd", "quartzGroup")
.build();
If I try to schedule the job, it throws an error Based on configured schedule, the given trigger 'quartzGroup.eventStartCron' will never fire.
Why isn't getFinalFireTime giving me a date? Is there some other approach I need to use?

Do not fire trigger on app startup if trigger time expired. Quartz

I have a simple trigger which trigger a simple job (let's assume - send an email).
My trigger:
return newTrigger()
.withIdentity(name, group)
.withSchedule(
simpleSchedule()
.withMisfireHandlingInstructionNextWithExistingCount()
)
.startAt(triggerStartTime)
.usingJobData(JobDataMap(triggerData))
.withDescription(description)
.build()
But, imagine that service will not available at triggerStartTime fired time (I just shut down database and my service). Some time later, when I run my service again - in log I see, that the trigger was executed.
UPD #1:
It reproduces when I create simple trigger which should start the next minute, after that I shut down all environments (app+db) and then turn it on during the minute when trigger should fire. Check it:
16:00:00 create trigger which should fire 16:01:00
turn off all environments
wait 16:01:59
turn on and observe that trigger fire
But if I turn on all environments after 16:02:00 it will not fire trigger. It is very strange behavior. Also, I observe, that in this case trigger was not removed from database.
There is a property in quartz to control misfire threshold org.quartz.jobStore.misfireThreshold
The number of milliseconds the scheduler will 'tolerate' a trigger to pass its next-fire-time by, before being considered "misfired". The default value (if you don’t make an entry of this property in your configuration) is 60000 (60 seconds).
Link to configuration document
I think if the exceeded time is below 1 minute(default value), the scheduler still considers that job is pending for normal execution. Try playing with that number.
and this is the actual query fired to get the triggers to be executed, note the second condition in the below query is based on the misfireThreshold property
Link to query

How to start a spring data hadoop job later?

I'm new for SpringData Hadoop. I checkout some examples from www, such as [1]:https://github.com/pkainulainen/spring-data-apache-hadoop-examples/tree/master/mapreduce
All of them are configured to run at start-up:
<hdp:job-runner id="wordCountJobRunner" job-ref="wordCountJob" run-at-startup="true"/>
But I want to run the job via a Servlet. How to?
i think you have to try this:
http://quartz-scheduler.org/
examples of code you could see the official site, but here is some fragment:
// compute a time that is on the next round minute
Date runTime = evenMinuteDate(new Date());
// Trigger the job to run on the next round minute
Trigger trigger = newTrigger()
.withIdentity("trigger1", "group1")
.startAt(runTime)
.build();

Categories