Creating Drush ready batches with Drupal Batch API in Drupal 8/9

When certain operations take more time to execute than the normal PHP script, we tend to break them into a smaller batches which can be executed by a cron job to avoid PHP execution timeout errors and have a more balanced distribution of the server resources.

Drupal comes with an excellent Batch API which uses queue workers to simplify this for us. Example in this guide is done with the updated version of Batch API using the \Drupal\Core\Batch\BatchBuilder, which is basically just a object oriented version of previously procedural style Batch API. BatchBuilder was introduced with the Drupal core version 8.6.

The objective of this short guide is the following:

  • create service for creating batches using Drupal Batch API
  • create a Drupal form for running the batches
  • create a Drush command for running the batches

The end result will be a form for running batch processing as shown in the below (Image 1).

Drupal Batch API form
Image 1: Running batch processing with Drupal form

 

As a bonus we also create a Drush command which is used for running batch processing. This becomes really useful when batch processing should be executed on a scheduled basis using cron.

For demonstration purposes, service will generate an array of strings to be processed as "nodes". But you get the idea, instead of having list of strings, those can be real objects ready for batch processing. I will be using the placeholder namespace called modulename which can be renamed to whatever is needed.

First, we need to register batch service inside the modulename.services.yml file.

File name: modulename.services.yml

services:
  modulename.batch:
    class: 'Drupal\modulename\BatchService'
    arguments:
      - '@logger.factory'

Next, we add batch service files (interface and the batch service file itself).

File name: src/BatchServiceInterface.php

[github_embed:master/025-creating-drush-ready-batch-drupal-batch-api/BatchServiceInterface.php]

File name: src/BatchService.php

[github_embed:master/025-creating-drush-ready-batch-drupal-batch-api/BatchService.php]

Code for preparing batches is now ready. To make use of it we need a Drupal form and/or Drush command to execute it. Our form will be available in the administration area on the following path:   /admin/config/batch-form.

File name: modulename.routing.yml

modulename.batch_form:
  path: '/admin/config/batch-form'
  defaults:
    _form: 'Drupal\modulename\Form\BatchForm'
    _title: 'Batch form'
  requirements:
    _permission: 'administer site configuration'
  options:
    _admin_route: TRUE

File name: src/Form/BatchForm.php

[github_embed:master/025-creating-drush-ready-batch-drupal-batch-api/Form/BatchForm.php]

And for our last step we will register a new Drush command which will be used for running batch processing from CLI. Command also has the option to specify the batch size (something that form currently does not support). Default batch size is 10.

File name: drush.services.yml

modulename.batch_command:
    class: Drupal\modulename\Commands\BatchCommand
    arguments:
        - '@modulename.batch'
    tags:
        - { name: drush.command }

File name: src/Command/BatchCommand.php

[github_embed:master/025-creating-drush-ready-batch-drupal-batch-api/Command/BatchCommand.php]

That is it. We now can run our Drush command to start batch processing with batch size of 10. Image 2 shows the output from running batch operations by using Drush command:

drush modulename-batch:run --batch=10
Running batch processing using Drush command
Image 2: Running batch processing using Drush command

 

 

Add new comment

CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.