You are here

function ultimate_cron_cron_run in Ultimate Cron 8

Same name and namespace in other branches
  1. 7.2 ultimate_cron.module \ultimate_cron_cron_run()
  2. 7 ultimate_cron.module \ultimate_cron_cron_run()

The cron handler takes over the normal Drupal cron handler and runs the normal hook_cron() plus the hook_cronapi().

Parameters

boolean $return: return to caller if TRUE, otherwise exit().

4 calls to ultimate_cron_cron_run()
drush_ultimate_cron_cron_run in ./ultimate_cron.drush.inc
Run cron job(s)
ultimate_cron_cron_queue_info in ./ultimate_cron.module
Implements hook_cron_queue_info(). Used for code injection in order to hijack cron runs.
ultimate_cron_run_cron in ./ultimate_cron.admin.inc
Menu callback: runs cron and returns to status-report page.
_ultimate_cron_poorman in ./ultimate_cron.module
The actual poorman function

File

./ultimate_cron.module, line 253
@todo Add filter on overview page. @todo Add log view (with graph). @todo Make proper markup for overview page. @todo Refactor drush stuff, too many intimate relations with Background Process @todo Refactor Cron % offset stuff. Too mixed up and…

Code

function ultimate_cron_cron_run($return = FALSE) {
  if (state()
    ->get('system.install_task') != 'done') {
    return;
  }

  // Be other cron module friendly
  if (_ultimate_cron_incompatible_modules()) {
    return;
  }

  // If run from core cron through CLI then don't do anything (drush core-cron)
  if (!$return && drupal_is_cli()) {
    return;
  }

  // Acquire lock
  if (!lock()
    ->acquire('cron', 240.0)) {
    drupal_set_message(t('Ultimate Cron launcher already running'), 'error');
    return;
  }
  $msc = variable_get('ultimate_cron_simultaneous_connections', ULTIMATE_CRON_SIMULTANEOUS_CONNECTIONS);

  // Get list of cron hooks.
  $hooks = ultimate_cron_get_hooks();

  // Get schedule.
  $schedule = ultimate_cron_get_schedule($hooks);
  drupal_set_message(t('%jobs jobs scheduled for launch', array(
    '%jobs' => count($schedule),
  )));

  // Start the jobs. Keep launching jobs until X seconds into the request.
  @set_time_limit(120);
  $time = time();
  $expire = $time + variable_get('ultimate_cron_launch_window', ULTIMATE_CRON_LAUNCH_WINDOW);
  $running = array();
  $launched = 0;
  $handle_prefix = variable_get('ultimate_cron_handle_prefix', ULTIMATE_CRON_HANDLE_PREFIX);

  // Try to launch jobs within the given time frame
  while (!empty($schedule) && time() < $expire) {
    $running_processes = db_select('background_process', 'bp')
      ->fields('bp', array(
      'handle',
    ))
      ->condition('bp.handle', $handle_prefix . '%', 'LIKE')
      ->countQuery()
      ->execute()
      ->fetchField();

    // Launch jobs.
    reset($schedule);
    while ((list($name, $hook) = each($schedule)) && time() < $expire) {

      // Congestion protection
      if (empty($hook['override_congestion_protection']) && $running_processes >= $msc) {
        continue;
      }
      if (empty($hook['force_run']) && !ultimate_cron_hook_should_run($hook)) {
        unset($schedule[$name]);
        continue;
      }
      $result = ultimate_cron_run_hook($name, $hook);

      // Handle errors.
      if ($result) {
        $handle = $handle_prefix . $name;
        $running[$handle] = $result;
        unset($schedule[$name]);
        $launched++;
        $running_processes++;
      }
      else {
        if ($result === FALSE) {

          // Could not get lock, skip job.
          unset($schedule[$name]);
        }
        else {

          // Failed to start, retry next time.
          watchdog('ultimate_cron', "Error starting {$name}", array(), WATCHDOG_WARNING);
        }
      }
    }

    // Jobs running ... check for start
    if ($running) {
      $result = db_query("SELECT p.name FROM {progress} p WHERE p.name IN (:running)", array(
        ':running' => array_keys($running),
      ));
      while ($handle = $result
        ->fetchObject()) {
        fclose($running[$handle->name]);
        unset($running[$handle->name]);
      }
    }
    sleep(1);
  }

  // Close all jobs left
  if ($running) {
    foreach (array_keys($running) as $handle) {
      fclose($running[$handle]);
      unset($running[$handle]);
    }
  }

  // Update drupals cron timestamp, but don't clear the cache for all variables!
  $name = 'cron_last';
  $value = time();
  global $conf;
  db_merge('variable')
    ->key(array(
    'name' => $name,
  ))
    ->fields(array(
    'value' => serialize($value),
  ))
    ->execute();
  $conf[$name] = $value;
  drupal_set_message(t('%jobs jobs launched', array(
    '%jobs' => $launched,
  )));
  if (count($schedule)) {
    drupal_set_message(t('%jobs jobs failed to launch within %seconds seconds', array(
      '%jobs' => count($schedule),
      '%seconds' => variable_get('ultimate_cron_launch_window', ULTIMATE_CRON_LAUNCH_WINDOW),
    )), empty($schedule) ? 'status' : 'error');
    watchdog('ultimate_cron', '%jobs jobs failed to launch within %seconds seconds', array(
      '%jobs' => count($schedule),
      '%seconds' => variable_get('ultimate_cron_launch_window', ULTIMATE_CRON_LAUNCH_WINDOW),
    ), WATCHDOG_WARNING);
  }

  // Release the lock
  lock()
    ->release('cron');

  // And we're done ...
  if ($return) {
    return empty($schedule);
  }
  else {
    exit;
  }
}