1

I'm using batch API in a custom module to clone millions of nodes programmatically but I am facing an error:

An error occurred. /batch?id=7&op=do
Fatal error: Out of memory (allocated -1179648000) (tried to allocate 40961 bytes) in

I try to optimize my code using the varible $limit for processing by lot but it seem to be not work

For example I have 10 data in my database and I put $ limit = 5; and it recovers only 5 data

But according the document http://envisioninteractive.com/drupal/drupal-batch-api-in-a-nutshell/ the limit Set the number of nodes you want to create within a single iteration of the batch. This number should be pretty low as it is the reason why we're creating the batch process in the first place.

here is my code :

function mymodule_menu() {
      $items = array();
      $items['mymodule'] = array(
        'title' => t('Cloner une liste'),
        'page callback' => 'drupal_get_form',
        'page arguments' => array('mymodule_form'),
        'access arguments' => array('access content'),
        'type' => MENU_NORMAL_ITEM,
      );
      return $items;
}

function mymodule_form() {
      global $base_url;
      $return_url = $base_url .'/gestion_creche_liste/'.arg(1);
      $node_tmp = node_load(arg(1));
      $default = 'Clone de ' . $node_tmp->title;
      $form['title_liste'] = array(
        '#type' => 'textfield',
        '#title' => t('Title'),
        '#default_value' => $default,
        '#required' => TRUE,
      );
       $form['description_liste'] = array(
        '#type' => 'textarea',
        '#title' => t('Description'),
        '#required' => false,
      );
      $form['retour'] = array(
        '#type' => 'button',
        '#value' => t('Retour'),
        '#prefix' => '',
        '#attributes' => array('onClick' => "window.location.href='".$return_url."'; return true;"),
        '#post_render' => array('change_button_type'),
       );
      $form['submit'] = array(
        '#type' => 'submit',
        '#value' => t('Save')
      );
      return $form;
    }

function theme_questionnaire_etape_trois_formulaire($form){
      $output = '';
      $output .= '<p><label for="edit-title_liste_value"><span> Titre liste * : </span>';
      $output .= str_replace('div','t',drupal_render($form['title_liste']));
      $output .= '</label></p>';

      $output .= '<p><label for="edit-field_description_liste_value"><span>Description : </span>';
      $output .= str_replace('div','t',drupal_render($form['description_liste']));
      $output .= '</label></p>';

      $output .= '<div id="btn">';
      $output .= drupal_render($form['submit']);
      $output .= '</div>';
      $output .= drupal_render($form);
      return $output;
}     

function mymodule_form_submit($form, &$form_state) {    

    $batch = array(
        'operations' => array(
          array('batch_clonerliste_op',  array($form_state['values']['title_liste'],$form_state['values']['description_liste'])),
          array('batch_mymodule_op',  array(arg(1))),
          ),
        'finished' => 'batch_mymodule_finished',
        'title' => t('Processing Example Batch'),
        'init_message' => t('Clone is starting'),
        'progress_message' => t('Processed @current out of @total.'),
        'error_message' => t('Example Batch has encountered an error.'),
    );



     batch_set($batch);
}


function batch_clonerliste_op($options1,$options2,&$context) {
     if(!isset($context['sandbox']['progress'])) {
        $context['sandbox']['progress'] = 0;
        $context['sandbox']['max'] = 1;
      }
     $node_liste = new stdClass();
     $node_liste->type = 'liste';
     $node_liste->language = 'fr';
     $node_liste->title = $options1;
     $node_liste->field_description_liste[0]['value'] = $options2;
     node_save($node_liste);

     $context['results']['nid'] = $node_liste->nid;  
     $context['sandbox']['progress']++;
     $context['message'] = t('Now processing %node', array('%node' => $node_liste->title));        

     if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
            $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
     } 
}


function batch_mymodule_op($options3,&$context) {
     $nid_liste = $context['results']['nid'];
     $tmp = get_curent_creche_liste($options3);
     $total = $num_rows = db_result(
     db_query("SELECT COUNT(DISTINCT nid) FROM  {content_field_liste_creche} WHERE field_liste_creche_nid = '%s'",$options3)); 

     if (!isset($context['sandbox']['progress'])) {
        $context['sandbox']['progress'] = 0;
        $context['sandbox']['current_node'] = 0;
        $context['results'][] = 0;
        $context['sandbox']['max'] = $total;
      }

//in total i have 10 date inside my database for exemple and i set limit = 5 $limit = 5;

        $result = db_query_range("SELECT DISTINCT nid FROM {content_field_liste_creche}  where field_liste_creche_nid = %s and nid != %d", array($options3,$context['sandbox']['current_node']), 0, $limit);
  while ($row = db_fetch_array($result)) {
                   $node = node_load($row['nid'],NULL,TRUE);
                   $node->field_liste_creche[]['nid'] = $nid_liste;
                   $node = node_submit($node);
                   node_save($node);

                   $context['sandbox']['progress']++;
                   $context['results'][]++;
                   $context['sandbox']['current_node'] = $node->nid;
                   $context['message'] = t('Now processing %node', array('%node' => $node->title));        
          } 

     if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
            $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
     } 
}


function batch_mymodule_finished($success, $results, $operations) {
     if ($success) {
        $message = count($results)-2 .' processed.';
     }
     else {
        $error_operation = reset($operations);
        $message = 'An error occurred while processing ' . $error_operation[0] . ' with arguments :' . print_r($error_operation[0], TRUE);
     }
     drupal_set_message($message);
     drupal_set_message('Clone r&eacute;ussie');
     drupal_goto('gestion_liste');
}


function get_curent_creche_liste($nid_list){
      $nid_creche_list = array();
      $query = "SELECT DISTINCT nid FROM  content_field_liste_creche WHERE field_liste_creche_nid ='".$nid_list."'";
      $result = db_query($query);       
      while ($row =db_fetch_object($result)) {
         $nid_creche_list[] = $row->nid;
      }
      return $nid_creche_list;
}

thank you very much in advance for your help

Your Answer

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

Browse other questions tagged or ask your own question.