Skip to main content
3 of 4
edited tags
avpaderno
  • 97.9k
  • 15
  • 164
  • 284

Batch API timing out (running as one operation?)

I'm trying to print ~100 nodes worth of content (Performance Plans) out to the private file system using the batch API. My process works perfectly up until about 10 of them and then times out. The timeout page happens before it even gets to the batch page with the progress bar. It appears to me like it might be running all 100 as a single batch vs breaking them up. I'm not sure exactly what I'm missing... Any help would be greatly appreciate.

BulkPrintForm.php

<?php
 namespace Drupal\bulk_print_to_files\Form;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\node\Entity\Node;
 use Drupal\Core\Url;
/**
 * Class BulkAddForm.
 *
 * @package Drupal\create_perf_plan_for_new_year\Form
 */
class BulkPrintForm extends FormBase {
  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'bulk_print_form';
  }
  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['bulk_add'] = array(
      '#type' => 'submit',
      '#value' => $this->t('Print Performance Plans'),
    );
    return $form;
  }
  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $nids = \Drupal::entityQuery('node')
      ->condition('type','perf_plan')
      ->condition('field_performance_plan_year', 18)
      ->range(0, 100)
      ->sort('created' , 'DESC')
      //->condition('nid', 6273)
      ->execute();
    //$year = "1920"; //$year being left here as an example of passing a variable to the bulk process. Not currently in use.
    
    $operations = [];

    foreach ($nids as $nid) {
      $operations[] = [
        [
          $this->batchFunction($nid),
          [$nid]
        ],
      ];
    }

    $batch = array(
      'title' => t('Bulk Print happening within the Bulk Print Form file...'),
      'operations' => $operations,
      'progress_message' => t('Processed @current out of @total. Estimated time: @estimate.'),
      'init_message'=> t('Performance Plans are being printed to the private directory!'),
      'finished' => '\Drupal\bulk_print_to_files\BulkPrintNode::bulkPrintFinishedCallback',
      'error_message' => t('The migration process has encountered an error. (Make sure the folder you are placing these in exists!)'),
    );
    batch_set($batch);
  }
  function batchFunction($nid) {
    $print_engine = \Drupal::service('plugin.manager.entity_print.print_engine')->createSelectedInstance('pdf');
    $print_builder = \Drupal::service('entity_print.print_builder');
    $path = 'private';
    $filename = "perfplans/{$nid}.pdf";
    $nodes = \Drupal::entityTypeManager()->getStorage('node')->load($nid);
    $uri = $print_builder->savePrintable([$nodes], $print_engine, $path, $filename);
  }
}

BulkPrintNode.php

<?php
namespace Drupal\bulk_print_to_files;
use Drupal\node\Entity\Node;
use Drupal\Core\Url;

function bulkPrintFinishedCallback($success, $operations) {
    if ($success) {
      $message = 'Performance plan printed.';
      $type = 'status';
    }
    else {
      $message = t('Encountered an error during bulk performance plan creation.');
      $type = 'error';
    }
    drupal_set_message($message, $type);
  }
}

Is there a way to limit these to say doing 5 at a time and then moving on to another set? Im under the impression I just have the batching process setup incorrectly.