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.
Related
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.
I have a task that is scheduled periodically. Sometime it can take longer than expected.
I am trying to find a way to make sure that scheduling will be canceled in case the task is already running. All mechanisms I check will make the task wait and run it after the first finish
locking ofcourse will do the job but I'm looking of something more high level
Any Idea
You can use ScheduledExecutorService. scheduleAtFixedRate is probably what you want as it will wait for your tasks to finish, iff one takes longer than the rate you specify:
If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.
Example:
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(() -> {
// Body will be executed every second unless the previous task hasn't finished.
}, 0L, 1L, TimeUnit.SECONDS);
There is something called scheduleAtFixedRate and scheduleAtFixedDelay.
scheduleAtFixedRate will start another process at defined time, so if previous process is not completed, two processes will be running and it might cause race condition of running same thing twice.
scheduleAtFixedDelay will start after fixed time once a task is completed.
scheduleAtFixedRate vs scheduleWithFixedDelay
In Spring you can do this by using annotation:-
#Scheduled(fixedDelay =30000)
http://howtodoinjava.com/spring/spring-core/4-ways-to-schedule-tasks-in-spring-3-scheduled-example/
do you know Apache Camel framework?
It has a module called quartz2 and has a much possibility to scheduling any task.
try read this page:
http://camel.apache.org/quartz2.html
I need to implement a Quartz job that behaves differently depending on how many times it has been run.
What would you say is the best (or at least a good) way to do that ?
Keeping a counter as state doesn't seem to work since it looks like Quartz recreates it's jobs every time.
Thanks.
This is what the Quartz PersistJobDataAfterExecution annotation allows you to easily implement without using any extra framework / logic.
From PersistJobDataAfterExecution (Quartz 2.2.0) javadoc:
An annotation that marks a Job class as one that makes updates to its
JobDataMap during execution, and wishes the scheduler to re-store the
JobDataMap when execution completes.
So when your job starts you simply read your job execution counter from the JobDataMap that is passed to the job's execute method. If the counter is not present in the JobDataMap, you initialize it with 0. At the end of your job execution you increment the counter in the JobDataMap. This updated counter value will then be available during the next job execution.
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.
I am quite new to using Java SchedulerThreadPoolExecutor. I would like to ask if there is a way to implement a scheduler that matches the scenario:
At time t, a scheduler will take in all the tasks that are not processed and processed them.
At time t+1, there are new tasks coming but the scheduler is unable to take them since all the tasks at time t have not processed finished. Even if some of the task at time t has finished processing, the scheduler is unable to take in new task from time t+1 until all the tasks have completely processed. If that is the case, the scheduler will block the task at time t+1. Till all the task t+1 have fully processed, then the scheduler will take in new tasks at t+1.
It seems that you want to define task processing periods, where no task will cross a period boundary. Two questions/hints:
Why do you need to use SchedulerThreadPoolExecutor? Unless you intend to use its timer-like capabilities, which would probably conflict with your task period requirement anyway, a simple ThreadPoolExecutor should be enough.
Have you considered restructuring your code to use invokeAll()?