Asynchronous Job Processing Using Quartz.Net Jay Vilalta jay.vilalta@gmail.com
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 - Example public 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