asynchronous job processing using quartz.net jay vilalta [email protected]
TRANSCRIPT
Asynchronous Job ProcessingUsing Quartz.Net
What Is Quartz.Net
• Scheduler (think task scheduler)• Queue for asynchronous jobs• C# port of Quartz (java)• Apache license
Why Use Quartz.Net
• Scale out• Redundancy• Smart handling of failures• Job chaining (poor man’s workflow)• Custom scheduling
How Can I Run It
• Embedded in your application• As a stand alone windows service
The Basics
• Scheduler• Jobs• Triggers
Scheduler
• Runs jobs• Manages the scheduling
Jobs
• Do the work• Some built-in• Mostly roll you own• Implement IJob
Built-in Jobs
• FileScanJob: monitors last modified date• NativeJob: runs executables or batch files• NoOpJob: does nothing• SendMailJob: sends emails
Jobs - Examplepublic class MyJob : IJob { public void Execute(JobExecutionContext context) { try { int count= context.MergedJobDataMap.GetIntegerFromString(“count"); for (int i = 0; i < count; i++) { //do something useful } } catch (ApplicationException ex) { throw new JobExecutionException("Something happened", ex, false); } }}
Triggers
• Tell the scheduler when jobs should run• Some built-in– Simple Trigger– Cron Trigger– NthIncludedDayTrigger
• Custom Triggers
Simple Trigger
• Start Time• Repeat Count• Repeat Interval
Cron Trigger
• Similar to UNIX cron• Start Time• Cron Expression– “0 15 10 ? * *”– “0 0,15,30,45 * ? * *”
Custom Triggers
• No example this time• Implementing a trigger is not trivial• Must implement 11 methods• Must be able to determine next fire time
Scheduling
• Associate a job to a trigger• Multiple triggers can be set• When the trigger fires, the job runs
scheduler.ScheduleJob(jobDetail, trigger);
Advanced Features
• Listeners• Special Jobs• Remote management• Clustering• Plug-ins• Unit testing
Listeners
• Job Listeners• Trigger Listeners• Scheduler Listeners• Job and trigger listeners can be global
Job Listener Example
public class JobHistoryListener : IJobListener{
public void JobExecutionVetoed(…)public void JobToBeExecuted(…)public void JobWasExecuted(…)
}
Trigger Listener Example
public class MyTriggerListener:ITriggerListener{ public string Name public void TriggerComplete(…) public void TriggerFired(…) public void TriggerMisfired(…) public bool VetoJobExecution(…)}
Special Jobs
• Stateful Jobs• Interruptible Jobs
Stateful Jobs
• Only one can run at a time• Allow you to save/restore state• You must manage state yourself• Implement IStatefulJob
Interruptible Jobs
• Mechanism to interrupt long running jobs• You must implement yourself• Implement IInterruptableJob
Remote Management
• Scheduler can be managed remotely• Exposed via Remoting• Most scheduler functions available
JobFactory
• Instantiates jobs• Default factory creates a new instance• Create your own if you use DI or IoC container
Job Stores
• RAMJobStore• AdoJobStore– MySql– Oracle– Postgres– SQL Lite– SQL Server
Clustering
• Load balancing• Job Failover• Caveat: clocks synchronized within a second
Plug-ins
• JobInitializationPlugin• LoggingJobHistoryPlugin• LoggingTriggerHistoryPlugin• ShutdownHookPlugin
Plug-ins Stub
public class SamplePlugin : ISchedulerPlugin { public void Initialize(string name, IScheduler sched) public void Shutdown() public void Start() }
Unit Testing
• You can / should unit test your quartz classes• Use a mocking framework• Mock the Scheduler (IScheduler)• Mock a calendar (ICalendar)• Use mocks to create your context
Sample Unit Test[Test] public void ExecuteTests() { JobDetail detail = new JobDetail(); IScheduler scheduler = new Mock<IScheduler>().Object; ICalendar calendar = new Mock<ICalendar>().Object; IJob job = new NoOpJob(); detail.Name = "Test"; detail.JobDataMap.Add("SOMETHING", "ELSE"); TriggerFiredBundle bundle =
new TriggerFiredBundle(detail, new SimpleTrigger(), calendar, false, null, null, null, null); JobExecutionContext context = new JobExecutionContext(scheduler, bundle, job); JobHistoryListener listener = new JobHistoryListener(); listener.JobToBeExecuted(context); listener.JobWasExecuted(context, null); //methods return void so need to get creative to determine if execution was successful } }
Resources
Project Home: http://quartznet.sourceforge.net/
Mailing List:http://groups.google.com/group/quartznet
Getting Started:http://jvilalta.blogspot.com