Tuesday, February 8, 2011

New in Quartz.Net 2.0-No More IStatefulJob

NOTE: I'm now blogging at http://jayvilalta.com/blog and not updating this blog anymore. For information on the latest version of Quartz.Net, visit me there.

Welcome to the the third post of my New in Quartz.Net 2.0 series.

Goodbye IStatefulJob

Yes, it’s true. In Quartz.Net 2.0 the IStatefulJob has been marked as obsolete. To be sure, it’s still available to use, but if you are using IStatefulJobs you should think about migrating them to use the new Quartz.Net 2.0 features.

The Disallow Concurrent Execution Attribute

So how do I implement an IStatefulJob in Quartz.Net 2.0? Fortunately, it’s not very hard to do. You just need to mark your IJob with the new DisallowConcurrentExecutionAttribute. Any jobs that have this attribute set are only allowed to run one instance of the job at a time. Keep in mind that an instance is defined by a JobKey (job name and group combination), which means that if you have the same job type scheduled with a different job name or a different job group, you may get more than one instance of that type of job running at the same time.

The Persist Job Data After Execution Attribute

Seems simple enough so far? Well, it is! There is only one other thing to consider. If you want the scheduler to persist the job’s state between executions, you must also add the PersistJobDataAfterExecutionAttribute to the class. This attribute tells the scheduler that you would like for it store the job’s JobDataMap once it is finished executing.

One Last Thing

While you can use each of these attributes separately, if you are going to use the PersistJobDataAfterExecutionAttribute to persist your job’s state, you should always use the DisallowConcurrentExecutionAttribute, because if you don’t, you might find that your job state is corrupted due to race conditions.

Friday, February 4, 2011

New in Quartz.Net 2.0–Directory Scan Job

NOTE: I'm now blogging at http://jayvilalta.com/blog and not updating this blog anymore. For information on the latest version of Quartz.Net, visit me there.

This is the second post of the New in Quartz.Net 2.0 series. Today we will look at the DirectoryScanJob, which is a new job in Quartz.Net 2.0.
The DirectoryScanJob is very similar to the FileScanJob, which is available in Quartz.Net 1.0. As you can probably tell from the names, the main difference between the two jobs is that the DirectoryScanJob scans for changes in… you quessed it… a directory , whereas the FileScanJob scans for changes in… yes, you guessed it again… a file. If you’re not familiar with the FileScanJob, don’t worry, we will look at the DirectoryScanJob in detail.

Introducing the DirectoryScanJob

First, let’s take a look at what the documentation says about this new job:
“Inspects a directory and compares whether any files' "last modified dates" have changed since the last time it was inspected.  If one or more files have been updated (or created), the job invokes a "call-back" method on an identified DirectoryScanListener that can be found in the SchedulerContext.”
That seems pretty self explanatory, no? Basically, you tell the job that it needs to check a certain directory to see if new files have been added or if existing files have been modified. When the job is executed it checks the files and stores the file information in its JobDataMap. The next time the job runs, it compares the information stored in the job’s JobDataMap, with the files in the directory. If any changes are found, the job calls the FilesUpdatedOrAdded method of the IDirectoryScanListener that was configured for that job, passing in an arrary of FileInfo objects.

Configuring the DirectoryScanJob

To configure and use a DirectoryScanJob, you will need to set the following keys in the JobDataMap:
  1. DIRECTORY_NAME: this is the path to the directory that you want to monitor.
  2. DIRECTORY_SCAN_LISTENER_NAME: this is the name of the DirectoryScanListener that should called if changes are detected
  3. MINIMUM_UPDATE_AGE: this is an optional parameter which lets you specify how many milliseconds must have passed since the file’s last modified time in order to consider the file modified. If this parameter is not specified, it defaults to 5000 milliseconds.

Possible Uses for the DirectoryScanJob

There are many uses for the DirectoryScanJob, so let’s list a few here:
  • You could replace any FileWatcher type services that you might have implemented
  • Scan files uploaded by users for viruses
  • Schedule other jobs to process files that have been copied to the directory for processing
The next post in the series will cover a change to the IStatefulJob interface: it has been marked as obsolete and is replaced by a class attribute!