quartz if method takes longer then repeat interval start when finish - java

I have a job that runs every 2 minutes:
org.quartz.CronScheduleBuilder.cronSchedule("0 0/2 * * * ?").withMisfireHandlingInstructionDoNothing()
Currently, if the job takes more than 2 minutes, Quartz waits another 2 minutes to run it again.
How do I start it right away if it took more than the scheduled interval?
I do not want Quartz to create another job and run both concurrently, because in case the job always fails, I don't want to fill the job queue up, I want the job to run with at least a 2 minute interval.

Misfire instructions tell Quartz what to do when a job runs late.
If a job didn't fire on time because the scheduler was down, or because the previous run took longer than expected, or any other cause, that's a misfire. And you can use misfire instructions like withMisfireHandlingInstructionDoNothing() to tell Quartz what to do.
In this case, you're telling Quartz: "If this job takes longer than expected, that is my problem, not yours. Don't fire up another instance concurrently, don't wait for it to finish. Ignore it. Do nothing".
If you want to change this, you can use a different misfire instruction, like withMisfireHandlingInstructionFireAndProceed(), which will instruct Quartz to fire a misfired job as soon as the previous one finishes.
You can look up available misfire instructions for each type of schedule in the API Javadoc.

Related

Quartz Scheduler Triggers not respecting priority

Basically, I am using an implementation of Quartz Scheduler and I want multiple jobs to run at the same time but some should run before the others. For this, I have found the parameter "priority" for a Trigger.
SO let's say I have 4 jobs, each with its own trigger. I set the priorities like this:
job1 - priority 5
job2 - priority 3
job3 - priority 11
job4 - priority 8
I want them to be run in this order: job3, job4, job,1, job2
Out of 20 runs, only around 3 times I get the expected result. For the others, the first task to be run is pretty much random, and the rest are ordered correctly. One run would be like: job1, job3, job4, job2 OR job4, job3, job1, job2
Am I not understanding properly how priorities work in Quartz? I can't find exactly what is happening.
The issue here is that Quartz doesn't ensure that when you schedule multiple jobs at the same time with different priorities, you will get them in the order you want UNLESS you have the working thread already busy. Otherwise, if the working thread is not busy, it will pick up the job with the highest priority that you could schedule in the span of nanoseconds.
For my case, the thread was not busy so while I was scheduling all the jobs, quartz had time to pick up and process the first job I scheduled. The rest of the jobs had time to be scheduled while the thread was busy processing job1.
You guys can follow the message "batch aquisition of..." in order to track down the problem yourselves.
My solution is to use the method schedule for a List of jobs.

How to set new job each time with different interval

I'm pretty new to Quartz and I've come a cross the following requirement:
I need to create a scheduler that schedules single job that each time it ends it rescheduled but with calculated interval time.
For example:
1. Start job that ends after 15minutes, then when finished reschedule it to end after 1Hour, when finished reschedule it to end after 45 minutes...and so on...
The point is that when job finishes I dynamically calculate the next interval and need to fire the event again.
How to accomplish that with Quartz?
Thanks.
Provided you can trigger it explicitly for the first time, something like
scheduler.addJob(jobDetail, true);
scheduler.triggerJob(jobName, groupName); //(1)
and code the job class such a way that after its main work is done, calculate the next trigger time and schedule it before job exits. Something like
scheduler.scheduleJob(jobDetail, trigger); //(2)
Note that the the job trigger in code snippet (1) removes the job after its done. That means you will have to schedule it, in (2), as if its a new job as far as scheduler is concerned.

Task scheduling with Quartz

I am using Quartz for scheduling parallel tasks, How can I get job running time in Quartz?
JobExecutionContext expose a some useful methods:
getJobRunTime: returns the time only after the job has actually completed
(you may want to use a JobListener to call it when job finished the
execution).
getFireTime: get the actual time the job started, so you can the current Date to calculate the elapsed time (you can call this method even inside the Job itself).
Note: To know "how long it WILL takes to run one job" you have to implement on your own doing some simple math to get the % of completion. Quartz itself doesn't have such a feature.

Quartz next fire time is still previous trigger time?

I am using Quartz with Spring to schedule jobs. I have a job which has been scheduled to run every hour. The problem is that when the scheduled job takes more than an hour then the job's "next fire time" remains the old time and is not fired (since the fire time is already past).
My question is how can we change "next fire time" if the job takes more time than the scheduled time?
Try using #DisallowConcurrentExecution annotation. With this, you can ensure only one instance of your job would execute at one point of time i.e. (only one instance of jobdetail).
Hence, if your job is taking more time than 1 hour then this annotation will stop the
other instances (i.e other instances will wait until the first running job finishes the execution).
I just guessed ... not sure whether it will work or not.

How to get the result of a scheduled job in play-framework?

I have a job scheduled which runs every few minutes, But how do I get the result of this job when it is finished ?
The job gets data from the database and returns the result.
Since only Job.in() and Job.now() return a promise result , How do I get it from a Scheduled job that runs every few minutes .
I am using playframework 1.2.5Rc1
You will have to store the result somewhere else. Then you can look up the results when you need them. It doesn't really make sense to "return" a result from a scheduled job because you never really have a reference to them. The API could return a promise for the first scheduled job, but that would leave all the other scheduled jobs in the dark.
One thing you could do is have the scheduled job push results into a BlockingQueue. Then elsewhere in your code you can call the take() method which blocks until it can pull something out of the queue. This would kind of act like a promise that is continually replenished. It would also allow the queue to fill up with out needing to worry about handling each result immediately.

Categories