Quartz misfiring policies - java

I'm new to Quartz in java and I have a question regarding misfiring.
I have set up a SimpleTrigger which fires every 5 seconds. Sometimes the associated job takes over 5 seconds. I'd like to skip the job when that happens (the set interval has been reached by the Trigger). Going through the API I dont find a misfiring policy that would do that.
Any toughts?
Thank you for the help

There are a couple of different misfire policies that could work for you. Look at the javadocs here: http://www.quartz-scheduler.org/docs/api/1.8.0/org/quartz/SimpleTrigger.html paying attention to the static final constants that start with MISFIRE_INSTRUCTION_RESCHEDULE_*. There are a number of different behaviors in regards to the repeat count, but I think they'll accomplish what you're trying to do.

Related

cron library for java with 'spreading'

I'm looking for a cron scheduling system with the possibility to 'spread out' tasks. Lets say I need to do a bit of work at 'round about' 12 o clock. The 'round about' is defined as lets say +/- 30 minutes. I need such a thing for my automated update task to not have all my millions of customers (joking...) downloading updates at exact the same time and just blowing up my webserver...
I know little about the existing cron libraries in java. I know there are cronj or quarz and dozen other systems - but I can't find out if one of them is able to do what I'm looking for.
At least I can implement such a 'spreading' feature (don't know how to call it better) myself by using a normal cron job and trigger a new Plain-Old-TimerTask with a little bit of Math.round() thingy... But would be nice if there is a native possibility for this.
Thanks and greetings
This looks being easy to implement on your own.
Create a worker thread which gets a random timer, sleeps and wakes up.

Quartz recovering from multiple days misfire

I'm trying to set up Quartz for the first time, and forgive me if I am just not understanding something. I'm wondering what is the best way to accomplish the following:
How to set up a job that must run a daily email report, and also be able to recover from a missed trigger so that: 1) the job knows what day the trigger was SUPPOSED to fire on. and 2) if (god forbid) the server is down for 3 days, Quartz will recover by running three missed days consecutively, also informing the job of what day each job represents. (execution order is not really important as long as I know what day each represents)
Right now I am just doing:
Trigger trigger = newTrigger()
.withIdentity("dailyTrigger", "scheduledReportEmail")
.startNow()
.withSchedule(dailyAtHourAndMinute(0, 5) .withMisfireHandlingInstructionFireAndProceed())
.build();
This only seems to recover by running once, no matter how many days get missed. Is that correct?
One approach I thought about is basically setting up 31 daily triggers, for days 1-31. Clunky.. and what might happen in February for those extra days? Is this the best approach?
I've also got weekly and monthly triggers to deal with but I figure if we're down for three weeks then we have bigger things to worry about :)
thanks for any advice....
Your use case is pretty standard and supported by Quartz. You just need "ignore misfires" policy:
Trigger trigger = newTrigger()
.withIdentity("dailyTrigger", "scheduledReportEmail")
.withSchedule(dailyAtHourAndMinute(0, 5)
.withMisfireHandlingInstructionIgnoreMisfires())
.build();
This basically means: I don't care that the trigger(s) misfired, just run it as soon as possible (that is most likely at application startup).
To figure out when given trigger was suppose to run (what was the scheduled time as opposed to current time), run this in your job:
void execute(JobExecutionContext context) {
final Date scheduled = context.getScheduledFireTime()
//...
}
See also
difference between last actual and scheduled fire time
issue when using quartz withMisfireHandlingInstructionIgnoreMisfires
Quartz scheduler misfire instructions explained - my article describing various misfire instructions

How to simulate 'No. of occurrences' or 'Repeat Count' with CronTriggers in Java?

I am using the Quartz Scheduler (version 1.8.3 due to project constraints) and I as assigned the task of creating an "MS Outlook-like" scheduler for Jobs specific to my project. Everything seems fine to work fine but I have a really huge problem with CronTriggers (this problem also exists in version 2.1 of Quartz):
I am using CronTriggers for recurrence patterns of DAILY, WEEKLY and MONTHLY. In addition to the recurrence pattern, I also provide an option for 'No. of occurrences'. This has become the bane of my life! CronTrigger does not provide an option for 'repeatCount' like SimpleTriggers do (bug: https://jira.terracotta.org/jira/browse/QTZ-242?page=com.atlassian.jira.plugin.system.issuetabpanels%3Achangehistory-tabpanel). Apparently this may be fixed in version 2.2 but I cannot wait that long nor do I believe my problem is unique!
A few options that I deemed worthy of investigation:
Calculate the 'EndTime' for the CronTrigger but using my own logic - this fails to cover all possible cases and is only approximate at best even for simple cases.
Use a TriggerListener or JobListener to keep track of no. of iterations of the job since I just need the job to stop after 'N' iterations and I have a 1:1 mapping from Job instance to Trigger. This does not seem very feasible and/or efficient by any stretch of the imagination.
Could any of you who have used CronTriggers with the option of 'No. of occurrences' please give some insights on how to solve this conundrum?
It seems that Quartz have implemented something that can help: TriggerUtils.computeEndTimeToAllowParticularNumberOfFirings.
I haven't tested it yet, but this is the code I have wrote for now:
CronTrigger trigger = newTrigger()
.withSchedule(cronSchedule(cronExpression))
.build();
Date endDate = TriggerUtils.computeEndTimeToAllowParticularNumberOfFirings((OperableTrigger) trigger,
new BaseCalendar(Calendar.getInstance().getTimeZone()), 10);
trigger = trigger.getTriggerBuilder().endAt(endDate).build();
If this won't work, then as said here and here, you can't set a repeat count, and you should use TriggerListener.
In any case, version 2.2 doesn't have this feature.
Update
I've tested it, and it works.
Wy dont't you instead use the Simple Trigger? You would have the additional taks of calculating the time interval at the time of scheduling the job, but that will be a one time activity.

scheduleAtFixedRate slow / late

I'm using a ScheduledExecutorService to provide an update to a database every hour with the scheduleAtFixedRate method. The problem is that it gradually gets later - in long service I've been logging it and it's about a second a day.
I made a small class just to examine this aspect - seems to work fine when nothing is happening on the PC ( running WinXP ) but if things are going on it rapidly gets later. 18:00:00.5 last night was its first log and this morning was 09:00:00.5 then 10:00:05.9, 11:00:26.8, 12:00:45.3, 13:01:07.8...
I can attach the code although my example isn't the smallest.
Anyone else experienced this? Any ideas why this isn't working properly?
I can think of lots of ways around it but I'd really like to know why it doesn't work as advertised!
Thanks, Mike
This is normal AFAIK. With scheduleAtFixedRate, If any execution of this task takes longer than its period, then subsequent executions may start late. That being said, I'd recommend scheduleWithFixedDelay. This will ensure that tasks are carried out at the specified delay interval.

How to set a complex custom crontab in google-app-engine (java)?

I am building an app for which I need to set up cron jobs. What I want to do is to set the specific minutes in a hour where specific crons should run. For instance:
Task1 at 1st minute of the hour
Task2 on every second minute of the hour
Task3 every 2 minute only in the second half of the hour
Building this in the standard Unix cron format is reasonably straightforward, but could not figure out how to do it in the Google-App-Engine.
The documentation does not list any non-trivial examples. Any suggestions on how to do it? Examples would be excellent.
The documentation you linked to seems to indicate that it isn't possible to do what you want using only Cron for Java (unless they have an undocumented feature for it). In particular this doesn't appear to allow for multiple times.
time specifies the time of day, as HH:MM in 24 hour time.
The Python version says the exact same thing.
However, one solution (albeit somewhat more expensive in terms of CPU usage) would be to call a URL every minute, and from the handler for that URL, dispatch out to whatever other calls you need.
In other words, something like:
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/run-scheduled-tasks</url>
<description>Run all scheduled tasks</description>
<schedule>every 1 minutes</schedule>
</cron>
</cronentries>
Then in run-scheduled-tasks, check a database for when each task last run, and if your complex condition for triggering them has occurred since then.
If the documentation is correct you can't get as granular as you are wanting. Doesn't look like they support picking a particular minute of the hour. Or a subset of an hour.
You might have to get creative. Why do you need such specific timing?
This may seem silly. Write three servlet. And schedule them from another UNIX machine on the other part of the world :D. Or even you can write a java app to do it. enjoy
Have a look at Quartz and see if that'll solve your problem.

Categories

Resources