How to call a CronTriggerBean stored in a JDBCJobStore? - quartz-scheduler

I need some help. I am using Quartz Scheduling and have configured a CronTrigger to run each night at 10PM. I am using the JDBCJobStore to take advantage of the Clustering.
The job runs at 10PM every night but I want to be able to call the job programmatically to run it on the fly if needed but I still want to take advantage of the clustering(Ie. I don't want multiple people being able to run the job).
Is there a way to get the CronJob from the store and run it while still taking advantage of the clustering option? For example now, the 1st server that wakes up the job runs, when the other server in the cluster wakes up it doesn't run if the job is already started.
I am able to do this like this but it start as a separate job.... which is not what I want.
scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
/ Create the JobDetail
JobDetail jobDetail = new JobDetail("cronTrigger", Scheduler.DEFAULT_GROUP, MyCronJob.class);
// Create a trigger that fires once right away
Trigger trigger = TriggerUtils.makeImmediateTrigger(0, 0);
trigger.setName("FireOnceNowTrigger");
scheduler.scheduleJob(jobDetail, trigger);

Assuming you know the name of the job you have already stored ("storedJob"), does this work for you?
Trigger trigger = TriggerUtils.makeImmediateTrigger(0, 0);
trigger.setName("FireOnceNowTrigger");
trigger.setJobName("storedJob");
trigger.setJobGroup(Scheduler.DEFAULT_GROUP);
scheduler.scheduleJob(trigger);

Related

Quartz: Undesired multiple job run in same time

I have some jobs that run with their schedule, but when I have for example two jobs that run in same time Quartz start one of this jobs two or three times. Did someone have the same problem? And how can I resolve this?
I am not entirely sure, but there could be copule reasons,
1). you are creating a new scheduler instance everytime you trigger/schedule job
2). or you are running the same exact Execute method of a class or have same job running eveytime.
So, when you declare your scheduler, instead of working on some other instance of scheduler, use default scheduler all time, for e.g.,
private IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
that is what I have done and I have a lot notifications/jobs triggering using Quartz.Net and haven't faced any issue yet.
Let me know if any of this helps. Cheers!

Unable to avoid job triggering at Start up

I am using a batch process and i want it to run at a specific cron scheduled time. However, the job is getting triggered at the start up and again triggering at the scheduled time. I am trying to avoid the former however failing to do so. This is a sample repository which reproduces the same issue: https://github.com/ppanigrahi02/BatchJobWithScheduler. i am using the spring guide example https://github.com/spring-guides/gs-batch-processing and added a scheduler on top of it. I will really appreciate any leads.
The #Scheduled annotation used here will start the job immediately at startup and every 600000 milliseconds. If you want to specify an initial delay to wait before the first execution, you can use the initialDelay attribute of the annotation, something like:
#Scheduled(initialDelay = 600000, fixedRate = 600000)
Another option is to use the cron attribute and provide a cron expression. For more details about this annotation, you can check the reference documentation here: https://docs.spring.io/spring/docs/5.0.3.RELEASE/spring-framework-reference/integration.html#scheduling-annotation-support-scheduled

Setting up a Job Schedule

I currently have a setup that creates a job and then collect some metrics about the tasks in the job. I want to do something similar, but by setting a job schedule instead. In particular, I want to set a job schedule that wakes up at a recurrence interval that I specify, and run the same code that I was running when creating a job. What's the best way to go about doing that?
It seems that there is a CloudJobSchedule that I could use to set up my job schedule, but this only lets me create say a job manager task, and specify few properties. How can I run external code on the jobs created by the Job schedule?
It could also help to clarify how the CloudJobSchedule works. Specifically, after I commit my job schedule, what would happen programmatically. Does the code just move sequentially and run the rest of the code. In this case, does it make sense to get a reference to the last job created by the job schedule and run code on the job returned?
You'll want to create a CloudJobSchedule. You can specify the recurrence in the Schedule.
If you only need to run a single task per recurrence, your job manager task can simply be the task you need to run. If you need to run multiple tasks per job recurrence, your job manager needs to have logic to submit tasks to Batch and monitor for completion (if necessary).
When you submit a job schedule to Batch, your client side code will continue running. The behavior is no different than if you were submitting a regular job. You can retrieve the last job run via JobScheduleExecutionInformation and the RecentJob property.

How to add a new Job to a Quartz cluster that needs to start running during the rolling update of the cluster?

We have clustered Quartz scheduler runner on a couple of application nodes. The application nodes need to be updated, and for high-availability reasons, the update is done as rolling update.
Together with the update, we need to add a new job, and that job needs to start running immediately - i.e. it can't wait until all nodes have been updated. The problem is that I can't control which node will run the new job, and if one of the old nodes runs the job, the job instantiation will faill (with a ClassNotFoundException), the trigger will be set to the state ERROR and the job won't run again.
One solution for this problem would be to do two updates: one to add the class in all nodes, and one to add the trigger. The main reason against this approach is that our ops procedures don't support this.
So is there also a way to schedule the new job and make it run reliably with a single update?
I just tried it and it turned out that Quartz gets a ClassCastException while trying acquire the trigger. The exception is wrapped into a JobPersistenceException and the trigger is left in WAITING state.
So, although this could cause an error log entry in one of the old nodes, Quartz doesn't leave the trigger in a non-working state.

Run scheduler to execute jobs at an interval from the completion of the previous job

I need to create schedulers to execute jobs(class files) at specified intervals..For Now, I'm using Quartz Scheduler which triggers the jobs at defined intervals from the time of triggering of it.
For Eg: Consider I'm giving a cron expression to run for every one hour starting at morning 9.My first run will be at 9 and my second run will be at 10 and so on.
If my job is taking 20 minutes to execute then in that case this method is not that much efficient.
What I need to do is to schedule a job for every one hour from the completion time of the previously ran job
For Eg: Consider my job to run every one hour is triggered at 9 and for the first run it took 20 minutes to run, so for the next time the job should trigger only at 10:20 instead of 10 (ie., one hour from the completion of previous ran job)
I need to know whether there are any methods in Quartz Scheduling to achieve this or any other logic I need to do.
If anyone could help me out on this,it would be very helpful for me.
You can easily achieve this by job-chaining your job executions. There are various approaches you can choose from:
(1) Implement a Quartz JobListener and in its jobWasExecuted method, that is invoked by Quartz whenever a job finishes executing, re-fire your job.
(2) Look at the Quartz JobChainingJobListener that you can use to implement simple job chaining scenarios. Please note that the functionality of this listener is very limited as it does not allow you to insert delays between job executions, there is no support for conditions that must be met before target jobs are executed etc. But you can use it as a good starting point to implement (1).
(3) Use QuartzDesk (our commercial product) or any other product that allows you to create job chains while externalizing and managing all job dependencies outside of your application. A job chain can have multiple target jobs that can be executed immediately, with a fixed delay or at arbitrary time in the future produced by a JavaScript expression. It also allows you to implement somewhat more sophisticated works flows, such as firing a target job when multiple source jobs complete their execution etc. I am attaching screenshots showing you what a simple job chain that re-executes Job1 with a 1 minute delay upon Job1's completion (with any job execution status) looks like: