How to set new job each time with different interval - java

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.

Related

Quartz scheduler - synchronizing jobs

I use Quartz scheduler for executing 10 jobs. All of these jobs have their own trigger. So they are executed asynchronously.
However now I need 2 of these jobs to be executed in more specific way. Lets say that Job1 is executed every even minute and Job2 every odd minute. Now I want Job2 to wait for Job1 to be finished.
Example: Job1 starts to execute at 10:02. At 10:03 Job2's trigger is fired. But before Job2 starts to execute, it will look at Job1 if it has finished.
I found annotation #DisallowConcurrentExecution for job class that implements Job interface. I thought that this will do the thing, but then I read that it will only disallow concurrent execution of jobs with the same JobKey(name,group). But I cant have the same JobKey for my jobs. So this annnotation is good for just one job I guess.
Do you have some idea how I can solve my issue? Many thanks.
Check the details of existing running job with this call and take appropriate action..
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
Refer this Jobs status
You can define a static variable to mark Job1 finished or not. When you create Job2, in your code, you can check the static variable before execute.

quartz if method takes longer then repeat interval start when finish

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.

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.

interfere with ScheduledThreadPoolExecutor's schedule

I used ScheduledThreadPoolExecutor.scheduledAtFixedRate to schedule some task to run every dt interval.
But sometimes, I do want to force the task to be executed immediately. After the task has executed, I want the schedule to go back to normal. (ie., some dt amount of time after this 'forced' execution, the task should be executed again).
Is it possible to do that with ScheduledThreadPoolExecutor? Could you show me how? Some simple example would be great!
I suppose one could do this by simply shutting down the schedule, executing the task manually, and calling scheduleAtFixedRate again, but I'm wondering if that's good practice.
Thanks
That's a good question. Maybe you could call cancel() on the ScheduledFuture<T> that you received from calling scheduledAtFixedRate(), submit the task manually using submit(), and then reschedule your fixed rate task again when that Future comes back? You would have to check that the task isn't already running I suppose.
Some pseudocode...
ScheduledFuture<Thingy> sf = executor.scheduleAtFixedRate(myTask, etc...);
sf.cancel();
final Future<Thingy> f = executor.submit(myTask);
f.get();
sf = executor.scheduleAtFixedRate(myTask, etc...);
I've never done it, it's an interesting question.
For a one shot execution use
ScheduledFuture<Thingy> sf = executor.schedule(myTask, 0, SECONDS);
This will execute myTask once and immediate but won't stop executing the tasks scheduled before with an interval. Is that really a problem?

pausing job execution based on total number of jobs executed - quartz

Is it possible to change the CronTrigger state to WAITING or to some other value which stops the job execution till next day? I can pause the trigger which will stop job execution but then I have to manual resume this trigger.
Actually, I have a CronTrigger which executes job every day between say 8:00 AM - 12:00 PM, right now it's working fine but now I would like to add an aditional check that before executing every job it will check the total number of jobs executed and pause the execution till next day if the total executed jobs limit is reached.
You'll want to create a custom TriggerListener, which keeps track of the count, can veto job execution, and reschedules jobs for the next day (e.g. updates the triggers' startTime to "00:00:00" of the next day while leaving the cron expression to the same).

Categories