-
Dylan Tack
OpenSourcery Alumnus
hook_cron() is widely implemented in the Drupal ecosystem – but what if your modules have varying frequency needs? For example, perhaps you'd like your aggregator feeds to update every fifteen minutes, and notifications should fire every minute to keep emails timely. But system_cron() should run as infrequently as practicable, because it calls cache_clear_all()!
Here is a small cron.php replacement that accomplishes this task. Just plunk the file in your drupal root directory. (You could move it to your sites folder if you modified the include path.) Different cron jobs for each module or set of modules can now be configured.
<?php // $Id$ /** * @file * Handles incoming requests to fire off regularly-scheduled tasks (cron jobs). * * The file executes cron hooks selectively, instead of all-or-nothing. * This allows cron jobs to be configured with variable frequency. * Example usage: * * * * * * curl example.com/cron_selective.php?modules=notifications * *∕15 * * * * curl example.com/cron_selective.php?modules=aggregator * 0 0 * * * curl example.com/cron_selective.php?modules=system,dblog * */ include_once './includes/bootstrap.inc'; drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); $modules = array_intersect(module_list(), explode(',', $_GET['modules'])); drupal_cron_run_selective($modules); /** * Executes a cron run when called * @return * Returns TRUE if ran successfully */ function drupal_cron_run_selective($modules) { // If not in 'safe mode', increase the maximum execution time: if (!ini_get('safe_mode')) { set_time_limit(240); } // Fetch the cron semaphore $semaphore = variable_get('cron_semaphore', FALSE); if ($semaphore) { if (time() - $semaphore > 3600) { // Either cron has been running for more than an hour or the semaphore // was not reset due to a database error. watchdog('cron', 'Cron has been running for more than an hour and is most likely stuck.', array(), WATCHDOG_ERROR); // Release cron semaphore variable_del('cron_semaphore'); } else { // Cron is still running normally. watchdog('cron', 'Attempting to re-run cron while it is already running.', array(), WATCHDOG_WARNING); } } else { // Register shutdown callback register_shutdown_function('drupal_cron_cleanup'); // Lock cron semaphore variable_set('cron_semaphore', time()); // Iterate through the modules calling their cron handlers (if any): foreach ($modules as $module) { module_invoke($module, 'cron'); watchdog('cron', 'Selective cron run completed for %module.', array('%module' => $module), WATCHDOG_NOTICE); } // Release cron semaphore variable_del('cron_semaphore'); } }
Elegant Solution
It's amazing how this one line makes the magic happen
$modules = array_intersect(module_list(), explode(',', $_GET['modules']));Do you know if any of the contributed cron modules out there have similar functionality?
http://drupal.org/project/elysia_cron
http://drupal.org/project/supercron
I'll be linking to here from the boost issue queue.
http://drupal.org/node/331537
ps should you put some sort of wrapper around the get for security reasons?
elysia cron
You can do the same using the elysia_cron module. I've never tried supercron.
The caveat with elysia cron is that you need to replace the core provided version of cron.php with a version provided by the module or change the cron job command in crontab to point to the module's cron.php.
Th syntax for specifying jobs is crontab like.
Elysia cron and supercron
Elysia cron can run without replacing cron.php or calling another cron.php (you can do that just to increase performances a little).
The only thing needed is a change in the system crontab to run the standard cron.php every minute (or what's the frequency you need).
Supercron is working in a way to do a similar thing (execute a group of task in a selectable time period), but it's still work in progress.
Command Line
If cron.php could take command line input as well, that would be a great feature.
http://php.net/commandline
http://php.net/reserved.variables.argv
D7 Issue
Found the core issue for this feature request
http://drupal.org/node/19173
great idea
Hai,
Thanks for sharing this info.It will be useful for everyone who are building a corporate or business websites using drupal
Thanks
Spam
rel="nofollow" only works for the homepage field, not for embedded links like the above.
Elysia cron and supercron
I tried both supercron and elysia cron. Elysia cron can do what the above script does and lists all active cron jobs. Supercron can not be configured to run seperate tasks at custom intervals but like Elysia cron it list a complete overview of active cron tasks.
Oops~Your post is of great
Oops~Your post is of great value for a guy like me which is learning some basic web knowledge to get my own web to work.Thanks for your great job~
How can I used wiht boost
Hi,
I'm triying to used the script with the module boost with the next cron sentence:
.... /cron_selective.php?modules=boost
But the expirated pages are not clear, it's the right mode to call the cron for this module.
Regards.
Add your comment