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'); } }
Like many Drupal developers, at any particular time I'm running dozens of Apache virtual hosts on my workstation. This allows access to each project under a friendly url. We frequently create sites that employ SSL, which creates a wrinkle: 