Drupal 7 tip: Cron queues

Posted by: 
Dominique De Cooman

In drupal 6 when you wanted to handle stuff on cron you often created a table to store stuff that needed processing by some cron job later or at best you used the http://drupal.org/project/job_queue.

In drupal 7 we can use cron queues. What does it do? It helps you to store stuff that needs processing later on cron.

How to implement it?

For example we are creating organic groups which we use as subsites in our system. We want to fill these sites with default content. So when it is created we dont want the user to be waiting for that content generation or worse make him interrupt this process. So we have a cron queue to do the work.

We need to implement a hook_cron_queue_info() to notify drupal that a queue type exists. This defines a worker.

<?php
function so_schoolsite_cron_queue_info() {
  
$queues['so_school_site'] = array(
    
'worker callback' => 'so_schoolsite_create_default_site_content',
    
'time' => 60,
  );
  return 
$queues;
}
?>

We define the worker which will fill our subsite with default content.

<?php
function so_schoolsite_create_default_site_content($item) {
  
module_load_include('inc''dfc''/imports/migrate/schoofiches');
  if (
$item['gid'] && $item['nid']) {
    
$website_node node_load($item['gid']);
    
dfc_parse_schoolfiche_set_website_menu_items($website_node);

    
//Group default content creation
    
dfc_migrate_content_school_pages($website_node);
    
dfc_migrate_content_school_project($website_node); //generate default projects
    
dfc_migrate_content_school_photoalbum($website_node);
    
dfc_migrate_content_school_news($website_node);
    
dfc_migrate_content_school_calendar($website_node);

    
$website_node->field_status['und'][0]['value'] = 1;
    
    
$website_node->og_menu 1;
    
node_save($website_node);
    
    
watchdog('so_schoolsite''Default content for site gid:"%gid" (schoolfiche:"%nid") is created', array('%gid' => $item['gid'], '%nid' => $item['nid']));
  }
}

?>

Finally we want to created our queue so cron can pick it up.

<?php
/**
 * Implements hook_node_insert().
 * @param type $node 
 */
function so_schoolsite_node_insert($node) {
  if (
$node->type == 'so_school_schoolwebsite' && !isset($node->so_import)) {
    if (isset(
$node->field_schoolfiche_ref['und'][0]['nid']) && $node->field_schoolfiche_ref['und'][0]['nid']) {
      
$queue DrupalQueue::get('so_school_site');
      
$element = array('gid' => $node->nid'nid' => $node->field_schoolfiche_ref['und'][0]['nid']);
      
$queue->createItem($element);
    }
    else {
      
drupal_set_message(t('So_schoolsite has no reference to fiche please contact support'), 'error');
    }
  }
}
?>

Conclusion:
Use this cron queue system to handle jobs in the background.

Add new comment