QuartzNet - austincodecamp09

Download Report

Transcript QuartzNet - austincodecamp09

Asynchronous Job Processing
Using Quartz.Net
Jay Vilalta
[email protected]
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