2

I have implemented an approximately 1000 nodes update using hook_cron_queue_info() and hook_cron(). When I manually run cron job from the Drupal administration pages, I get a maximum time execution error; once this number is reduced by 10, it works fine.

Any suggestion?

function my_module_cron_queue_info() {  
  $queues['my_module_batch'] = array(
    'worker callback' => '_my_module_process_queue',
    'skip on cron' => FALSE,
  );
  return $queues;
}


function my_module_cron() {
  $contents = lade_update_nodes(); // get node list for updation
  $queue = DrupalQueue::get('my_module_batch');
  foreach ($contents as $p_file) {
    $process_data = array(
    // set values for process
    );
    $queue->createItem($process_data);
  }
}

function _my_module_process_queue($arr) {
    // code for updation
    watchdog('update node', 'Custom msg');
}
2
  • It's not completely clear; are you processing 1.000 nodes in one batch, or it's 1.000 nodes in total? Apr 10 '16 at 7:40
  • @Aram Boyajyan: I have added my code with post. Apr 10 '16 at 8:01
3

To answer the question in the title, Drupal cron does check the time used to process the items in a queue, and by default it gives 15 seconds to each queue. This still doesn't avoid the total time given to all the queues doesn't exceed the limit, especially if the call to drupal_set_time_limit(240) (which would set the time limit to 240 seconds) doesn't have success.

Also, since the code used by Drupal is the following one (see drupal_cron_run()), if processing a single item in a queue requires more than the time assigned to processing a queue (for example 30 seconds instead of 15), Drupal cannot block processing a queue when the time assigned to a queue is passed.

  foreach ($queues as $queue_name => $info) {
    if (!empty($info['skip on cron'])) {
      // Do not run if queue wants to skip.
      continue;
    }
    $callback = $info['worker callback'];
    $end = time() + (isset($info['time']) ? $info['time'] : 15);
    $queue = DrupalQueue::get($queue_name);
    while (time() < $end && ($item = $queue->claimItem())) {
      try {
        call_user_func($callback, $item->data);
        $queue->deleteItem($item);
      }
      catch (Exception $e) {
        // In case of exception log it and leave the item in the queue
        // to be processed again later.
        watchdog_exception('cron', $e);
      }
    }
  }

If you get a maximum time execution error, you can just limit the number of processed items, or assign less time for your queue.

function my_module_cron_queue_info() {  
  $queues['my_module_batch'] = array(
    'worker callback' => '_my_module_process_queue',
    'time' => 3,
  );
  return $queues;
}

As side note, setting 'skip on cron' to FALSE is useless, as Drupal assumes it is FALSE by default. In fact, it uses if (!empty($info['skip on cron'])) {} to decide if skipping a queue; !empty($info['skip on cron']) is FALSE when $info['skip on cron'] is not set, or when it is set to FALSE.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.