Magento has a really neat cron system that lets developers run scheduled jobs at defined intervals, much like the cron service found on most Unix-like systems. I wrote a post a over two years ago covering how to use the Magento cron, but in this post I explore mechanism behind the service.
The cron, as a Magento module, is a simple example of how things should be done with Magento, which is why I think it makes it an interesting service to examine.
We put an entry in our Operating System’s crontab to handle Magento’s crontab with something like:
*/5 * * * * www-data /usr/bin/php /var/www/magento/cron.php. We generally set things off every 5 minutes, which is more than often enough for any store.
Magento makes heavy use of the Event-Observer pattern to allow modules to hook into key points, or events, through the course of normal program execution. The cron service takes advantage of this by defining a new event called the crontab in the file cron.php. This allows for the actual cron.php script to be very concise (only 8 lines, really) and easily extensible, so that if another module needs to hook into the raw loading of the cron.php script, then it can do so through this same event.
Modules wishing to make use of the cron do not hook directly into this crontab event otherwise they’d either have their event fired every time we hit cron.php, remember we’re running it every 5 minutes at the moment, or they’d have to manage their own inhibition parameters, e.g. make sure that they only run every day, or every 3 hours, etc.
Instead they define a config.xml, discussed here, entry describing the model and method to be run, as well as a standard cron expression to define how frequent the method should be executed.
The method that’s executed, by default when the crontab event is fired is
cron/observer::dispatch which handles the schedule and execution of the jobs defined in the various config.xml files. The dispatch function takes care of:
Magento converts the config.xml into pending jobs in the database. Once conditions are satisfied, i.e. the desired execution time is now or in the past and the deadline has not been missed, the job will be executed and it’s status updated to complete.
Cron instances could, quite easily, take longer than 5 minutes which, with our setup, would cause another call to the cron.php script. To avoid duplicate runs, Magento locks the job once the job has been started.
And that’s it really. A really concise module, with most of the heavy lifting done by the cron/schedule model handling the cron expression parsing. A perfect example of a module that uses Event-Observers well, custom
config.xml entries and a database resource.