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?
Not directly AFAIK, but it should be not too hard to use a TriggerListener to implement such a functionality (a TriggerListener is run both a start and end of jobs, and you can set them up for individual triggers or trigger groups).
EDIT: there is even a specific FAQ Topic about this problem:
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.
Related
Say i have job which needs to be executed at fixed times in a day like below,
"05:00, 06:10, 07:30, 08:15, 09:05, 10:35"
How could i build a Trigger for this in Quartz ?
I couldnt find the way to achieve this out-of-the-box.
I see two ways to solve your problem:
1. Multiple triggers (recommended).
The most obvious and easy way to set the unusual scheduling for you job is to combine several triggers.
Quartz allows to set as much triggers as you want for single JobDetail.
2. Implement your own trigger.
It is more complicated way, applicable only if you must use only one trigger.
You could implement org.quartz.Trigger interface or any subinterfaces to set yourown rules.
I saw the sample dynamic trigger in github and it is using fixed rate/delay but is it possible to implement dynamic trigger with cron expression where once job is completed with custom exit code we want the cron expression in such a way that it no longer poll for that day or change cron expressin to start polling from diff time onwards.
Unfortunately org.springframework.scheduling.support.CronTrigger uses final field, so we can't change its state at runtime. Therefore any ideas to seek the way how to change cron-expression value is a waste of time.
From other let's take a look at this as just a time producer solution to notify the scheduler when to start a provided task.
In other words here is a Trigger contract source code:
public interface Trigger {
Date nextExecutionTime(TriggerContext triggerContext);
}
So, what our solution must supply is just only returning the specific Date for each nextExecutionTime invocation.
Only what you need to do here is that dynamic trigger implementation which fits to your requirements.
Right, it might be a bit difficult to reach cron-similar behavior, but there is no choice for you right now...
Although you can stop() you adapter after the task, inject a new CronTrigger to it and start() it again.
You can write a custom trigger that simply wraps a CronTrigger and you can replace the delegate CronTrigger at will.
However, a limitation of the Trigger mechanism is you can't change an existing schedule.
If you are running your job on the poller thread, then you can change the trigger before the poller thread returns (and calls the trigger to find the next execution time).
Spring Integration 4.2 (currently at milestone 2) has conditional pollers which will make things like this a little easier.
The result of SqlWorkflowInstanceStore.WaitForEvents does not tell me what type of workflow is runnable. The constructor of WorkflowApplication takes a workflow definition, and at a minimum, I need to be able to store a workflow ID in the store and query it, so that I can determine which workflow definition to load for the WorkflowApplication.
I also don't want to create a SqlWorkflowInstanceStore for each custom workflow type, since there may be thousands of different workflows.
I thought about trying to use WorkflowServiceHost, but not every workflow has a Receive activity and I don't think it is feasible to have thousands of WorkflowServiceHosts running, each supporting a different workflow type.
Ideally, I just want to query the database for a runnable workflow, determine its workflow definition ID, load the appropriate XAML from a workflow definition table, instantiate WorkflowApplication with the workflow definition, and call LoadRunnableInstance().
I would like to have a way to correlate which workflow is related to a given HasRunnableWorkflowEvent raised by the SqlWorkflowInstanceStore (along with the custom workflow definition ID), or have an alternate way of supporting potentially thousands of different custom workflow types created at runtime. I must also load balance the execution of workflows across multiple application servers.
There's a free product from Microsoft that does pretty much everything you say there, and then some. Oh, and it's excellent too.
Windows Server AppFabric. No, not Azure.
http://www.microsoft.com/windowsserver2008/en/us/app-main.aspx
-Oisin
I have 7 workflow that need to execute; that need to run in certain order ? Is there any scheduling service for this in wf4 or any other approach i can use?
Ocean
If you need to run them sequentially in a certain order, why not just create another workflow and put all 7 of your workflows as activities in a top sequential activity?
If you create an activity that derives fron NativeActivity you can schedule child activities in any order you like. That is the closest thing to a "SchedulerService" I can think of.
However you have to know the activites you want to run at compile time. You can only arrange the order differently using this approach.
If you don't know which activities you want to use at compile time you could use a parent/child technique I showed on my blog WF4 How To Invoke a Child Workflow as XAML
I am working on a Windows service which needs to schedule tasks whenever one of it's web services is called. This could happen hundreds of times per second in a worst case scenario. The task needs to wait a period of time, typically a minute or two, then call a method passing a parameter.
We tried to build our own scheduler class to do this:
public void ScheduleTask<T>(TimeSpan delay, Action<T> task, T arg)
{
Thread.Sleep(delay);
threadPool.ExecuteAsync(task, arg);
}
But we figured this wouldn't be appropriate because we could theoretically end up with hundreds of Thread Pool threads all waiting. I am under the impression that there is a finite number of Thread Pool threads available and that this could potentially lock up the system.
I then turned to Quartz.NET and read on their features page that:
Job class instances can be instantiated by Quartz.NET, or by your application's framework.
and on page 3 of their tutorial that the Scheduler creates instances of your Job class (not you) and as such:
it does not make sense to have data-members defined on the job class as their values would be 'cleared' every time the job executes.
Feel free to yell at me, but how do I get a reference to my Job class instance before it executes so I can set a property on it?
The property is doing the job of a
parameter so i have no interest in it
after the Job has executed.
I also want to minimise the number of
objects it takes to acheive this to
keep my code neat and simple.
Finally, I seriously dislike using
Dictionaries so would prefer to avoid the JobDataMap object.
I don't understand exactly what your use case is and why you would need to set a property on the job, but to answer your question: to get access to your job before it executes you need to create a job listener (implement IJobListener). The job listener gets called just before the job gets executed, so you could set a property at that point.
Some links:
The documentation on job listeners
I wrote a blog post detailing the creation of listeners, here.