I have two jobs running. First job polls data and updates the queue. Another one reads the queue and processes it. I need to pass fresh data to second job every time it runs. Second jobs runs every 10 seconds. So I need to pass fresh JobDataMap every time the 2nd job runs.
I read Quartz documentation on this one. But its not clear. Should I use one JobDataMap and pass it back and forth filling it up? Or is there a way to create new JobDataMap and pass it to job every time the job runs.
Any idea?
Related
Is there any way to persist JobDataMap without triggering/scheduling any jobs? Can I afterwards (on callback) start a Job with the stored JobDataMap?
I have many jobs scheduled with Quartz an I pass JobDataMap to those jobs:
scheduler.triggerJob(new JobKey("job-name", "job-group"), myJobDataMap);
Now I need to implement job queue since there are jobs which can't be launched in parallel. The problem is that state (JobDataMap) for some jobs is passed from client, and should be persisted for queueing purposes. In other hand I can't schedule job on user request since I don't know when it should be executed! (It should be executed right after previous job)
Yes.
You can use the method addJob(JobDetail, boolean) to add a new job to the Scheduler without actually scheduling it. Quoting the docs:
The Job will be 'dormant' until it is scheduled with a Trigger, or Scheduler.triggerJob() is called for it.
Your data map would be part of the JobDetail parameter.
I have a QUARTZ JOB which is starts every 10 minutes.
If a JOB doesn't finish in 10 minutes, in the next 10th minute another JOB will start.
What I want is: the next JOB (after every 10 minute) should start only, if the previous JOB has finished running. Is there any way to do it?
Quartz Documentation
#DisallowConcurrentExecution is an annotation that can be added to the
Job class that tells Quartz not to execute multiple instances of a
given job definition (that refers to the given job class)
concurrently. Notice the wording there, as it was chosen very
carefully. In the example from the previous section, if
"SalesReportJob" has this annotation, than only one instance of
"SalesReportForJoe" can execute at a given time, but it can execute
concurrently with an instance of "SalesReportForMike". The constraint
is based upon an instance definition (JobDetail), not on instances of
the job class. However, it was decided (during the design of Quartz)
to have the annotation carried on the class itself, because it does
often make a difference to how the class is coded.
If you dont want SalesReportForMike and SalesReportForJoe to run concurrently ,then you can set the scheduler's ThreadPool size to 1. So at any given time only one job will run.
Also take a look at StatefulJob
Take a look at the DisallowConcurrentExecution annotation which will prevent multiple instances of the same job to run at the same time.
Would you please explain to me the exact mean of the StatefulJob in quartz and it's difference with none StatefulJob?
StatefulJob interface, provides 2 things,
first: only one job will be run any time
second: in (SimpleTriggerBean) you will not worry about your job running duration. it means that the next run will be done after delay time after ending of previous one.
StatefulJob guarantees only one job will be running at one time. For example, if you schedule your job to run every 1 minute, but your job took 5 minutes to complete, then the job will not be run again until the previous job has completed.
This is useful to make sure there is only one job running at any given time.
The next job will be run on the next schedule, not immediately after the previous job completed.
jobDetail.getJobDataMap().put("type","FULL");
This line is will decide we are using statefull or non-statefull.
If we are passing the argument then it will be statefull.
With out statefull there is no way to pass the arguments in execute method
In state full while execution time if we modify any value then the execution job will be lost it wont re-triggered at simultaneous process time.
Only one job will execute at a time the second will be sleep until the first one is completed.
In multi scheduling process the second job argument will be share to first job at run time. this is one type of disadvantage in multi scheduling process.
I have started using quartz scheduler in my application.I want to know whether we can find the actual start time of a scheduler and the actual time at which the scheduler ends.
You can use a JobListener for that.
The method jobToBeExecuted runs before the job starts and jobWasExecuted after it ends.
EDIT:
To further expand on the issue:
You can use the JobDetail object to store data about the job (look at getJobDataMap).
jobToBeExecuted method is called automatically each time the job is about to execute and it accepts a JobExecutionContext which has a method getJobDetails (look at section 1)
Same goes for jobWasExecuted, only this one is called after the job finished.
Look here for further information.
I have a Quartz job that has already been scheduled. I want to update the JobDataMap associated with it. If I get a JobDataMap with JobDataMap jobDataMap = scheduler.getJobDetail(....).getJobDataMap(), is that map "live"? ie. if I change it, will it be persisted in the scheduler? If not, how do I persist it?
In quartz 2.0. StatefulJob is deprecated. In order to persist the job data map, use #PersistJobDataAfterExecution on the job class. It usually goes with #DisallowConcurrentExecution.
I had a similar problem: I have a secondly trigger which fires a stateful job that works on a queue in the job's data map. Every time the job fires, it polls from the queue and performs some work on the polled element. With each job execution, the queue has one less element (the queue is updated correctly from within the job). When the queue is empty, the job unschedules itself.
I wanted to be able to externally update the list of arguments of an ongoing job/trigger to provide more arguments to the queue. However, just retrieving the data map and updating the queue was not enough (the following execution shows the queue is not updated). The problem is that Quartz only updates the job data map of a job instance after execution.
Here's the solution I found:
JobDetail jobDetail = scheduler.getJobDetail("myJob", "myGroup");
jobDetail.getJobDataMap.put("jobQueue", updatedQueue);
scheduler.addJob(jobDetail, true);
The last line instructs Quartz to replace the stored job with the one you are providing. The next time the job is fired it will see the updated queue.
See http://www.quartz-scheduler.org/docs/tutorial/TutorialLesson03.html:
A Job instance can be defined as
"stateful" or "non-stateful".
Non-stateful jobs only have their
JobDataMap stored at the time they are
added to the scheduler. This means
that any changes made to the contents
of the job data map during execution
of the job will be lost, and will not
seen by the job the next time it
executes.
...a stateful job is just the opposite -
its JobDataMap is re-stored after
every execution of the job.
You 'mark' a Job as stateful by having it implement the StatefulJob
interface, rather than the Job
interface.