You are here

function ultimate_cron_cron in Ultimate Cron 6

Same name and namespace in other branches
  1. 8.2 ultimate_cron.module \ultimate_cron_cron()

Implementation of hook_cron().

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().

3 calls to ultimate_cron_cron()
drush_ultimate_cron_cron_run in ./ultimate_cron.drush.inc
Run cron job(s)
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 249
@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($return = FALSE) {
  if (variable_get('install_task', FALSE) != '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 && function_exists('drush_verify_cli') && drush_verify_cli()) {
    return;
  }
  $msc = variable_get('ultimate_cron_simultaneous_connections', ULTIMATE_CRON_SIMULTANEOUS_CONNECTIONS);

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

  // If this is run manually and a lock can be acquired, then run unsafe hooks.
  $schedule_unsafe = $return && lock_acquire('cron', 120.0);

  // Get schedule.
  $schedule = ultimate_cron_get_schedule($hooks, $schedule_unsafe);
  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_result(db_query("SELECT COUNT(1) FROM {background_process} WHERE handle LIKE '%s%%'", $handle_prefix));

    // 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) {
      $placeholder = db_placeholders(array_keys($running), 'varchar');
      $result = db_query("SELECT p.name FROM {progress} p WHERE p.name IN ({$placeholder})", array_keys($running));
      while ($handle = db_fetch_object($result)) {
        if (is_resource($running[$handle->name])) {
          fclose($running[$handle->name]);
        }
        unset($running[$handle->name]);
      }
    }
    sleep(1);
  }

  // Close all jobs left
  if ($running) {
    foreach (array_keys($running) as $handle) {
      if (is_resource($running[$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;
  $conf[$name] = $value;
  $serialized_value = serialize($value);
  db_query("UPDATE {variable} SET value = '%s' WHERE name = '%s'", $serialized_value, $name);
  if (!db_affected_rows()) {
    @db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", $name, $serialized_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);
  }

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

    // Release cron semaphore
    variable_del('cron_semaphore');
    lock_release('cron');
    exit;
  }
}