I'm working on a project with Quartz and has been a problem with the dependencies with jobs.
we have a setup where A and B aren't dependent on eachother, though C is:
A and B can run at the same time, but C can only run when both A and B are complete.
Is there a way to set this kind of scenario up in Quartz, so that C will only trigger when A and B finish?
You should probably upgrade to Quartz 3.1 and start using the built-in dependency injection support. You can use the Quartz.Spi.IJobFactory interface and implement it. The Quartz documentations states: When a trigger fires, the Job it is associated to is instantiated via the JobFactory configured on the Scheduler.
By default Quartz will try to resolve job's type from container and if there's no explicit registration Quartz will use ActivatorUtilities to construct job and inject it's dependencies via constructor. Job should have only one public constructor.
As of Quartz.NET 3.3.2 all jobs produced by the default job factory are scoped jobs, you should no longer use UseMicrosoftDependencyInjectionScopedJobFactory.
The scheduler will use the new NinjectJobFactory we made to create instances of our jobs when Quartz.NET asks for them. Once this binding is added we can add all of the bindings that our job’s require. For our DogJob example, we need to create a binding that will give an instance of GoldenRetriever whenever IDog is asked for:
I think this is the current way to do it: http://www.quartz-scheduler.org/documentation/faq#FAQ-chain
Based on this FAQ, you can create a job listener that waits for A and B to finish, and then schedule Job C once that happens.
PS: Here's the text in case the link changes:
How do I chain Job execution? Or, how do I create a workflow?
There currently is no "direct" or "free" way to chain triggers with Quartz. However there are several ways you can accomplish it without much effort. Below is an outline of a couple approaches:
One way is to use a listener (i.e. a TriggerListener, JobListener or SchedulerListener) that can notice the completion of a job/trigger and then immediately schedule a new trigger to fire. This approach can get a bit involved, since you'll have to inform the listener which job follows which - and you may need to worry about persistence of this information. See the listener org.quartz.listeners.JobChainingJobListener which ships with Quartz - as it already has some of this functionality.
Another way is to build a Job that contains within its JobDataMap the name of the next job to fire, and as the job completes (the last step in its execute() method) have the job schedule the next job. Several people are doing this and have had good luck. Most have made a base (abstract) class that is a Job that knows how to get the job name and group out of the JobDataMap using pre-defined keys (constants) and contains code to schedule the identified job. This abstract Job's implementation of execute() delegates to an abstract template method such as "doWork()" (where the extending Job class's real work goes) and then it contains the code for scheduling the follow-up job. Then they simply make extensions of this class that included the work the job should do. The usage of 'durable' jobs, or the overloaded addJob(JobDetail, boolean, boolean) method (added in Quartz 2.2) helps the application define all the jobs at once with their proper data, without yet creating triggers to fire them (other than one trigger to fire the first job in the chain).
In the future, Quartz will provide a much cleaner way to do this, but until then, you'll have to use one of the above approaches, or think of yet another that works better for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With