SlideShare a Scribd company logo
Better Drupal 8 Batches
Cause “just do it like D7” is like using hand powered a ferry: it
gets the job done in the hardest way possible.
Batch Overview
● Drupal batch processing is great for doing long running jobs when you can
leave a browser open or you need a simple UI to a process.
● It is just as easy for a developer to use as Feeds and more reliable.
● It is built around the best concepts Drupal 5 could give us, the DX is just a
little wonky.
● All the advice on D8 batches basically says: “It didn’t change”. But everything
else did!
Quick batch how-to
A typical batch process starts with a form, that generates an array of tasks,
which reference PHP functions that implement callback_batch_operation(), and
finally calls function that implements callback_batch_finish().
callback_batch_operation() each call to is passed a collection of parameters
followed by an array called $context that allows for intra and inter task messages.
Any given task can be called once, or a thousand times.
Task runs should be short so Drupal can reboot strap as needed.
callback_batch_finish() is called when everything is done, or fails, to report
outcome.
Why do we need a new interface?
We don’t. Then why
are we
here?
The current solution
works well enough to
drive the Drupal 8
installer, bulk operations,
and lots of other things.
Why do we want a new interface?
● All the advice on D8 batches basically says: “It didn’t change”. But everything
else did!
● The batch array definitions are obscure and hard to remember.
● Current patterns require either inserting procedural code into your project or
your create a class with a bunch of static functions.
○ Both limit your ease of access to other Drupal services since you are pulling them into a global
or static context.
● Having a service that can run as a more standard service it makes your new
code more standard with everything else.
Introducing Batch Service Interface
Sandbox Project: https://www.drupal.org/sandbox/acrosman/3025562
Provides an interface that defines the service, an abstract class of helper functions
to do all the static work, and a silly example module to prove it works. All you have
to do is define the service, define the form, provide your list of tasks (functions in
the class), and let it run. It handles array prep for batch, instantiating services, and
related elements.
Simple form with simple code
public function submitForm(array &$form, FormStateInterface $form_state) {
$data = [
'message_count' => $form_state->getValue('message_count'),
];
$batch = $this->exampleBatchService->generateBatchJob($data);
batch_set($batch);
}
Generate the batch job
public function generateBatchJob($data) {
$ops = [];
for ($i = 0; $i < $data['message_count']; $i++ ) {
$ops[] = [
'logMessage' => ['MessageIndex' => $i + 1],
];
}
return $this->prepBatchArray($this->t('Replace Users'), $this->t('Starting
Batch Processing'), $ops);
}
Define Worker Method
public function logMessage($data, &$context) {
// We could do something interesting here.
$this->logger->info($this->getRandomMessage());
if (!isset($context['results']['message_count'])) {
$context['results']['message_count'] = 0;
}
$context['results']['message_count']++;
}
And we’re done...
public function doFinishBatch($success, $results, $operations) {
drupal_set_message($this->t('Logged %count quotes', ['%count' =>
$results['message_count']]));
}
Okay there is a little funkiness
class ExampleBatchService extends AbstractBatchService {
/**
* Must be set in child classes to be the service name so the service can
* bootstrap itself.
*
* @var string
*/
protected static $serviceName = 'batch_example.example_batch';
Let’s see it go...then look at the code...
Related Core Effort
These will be better, if they are ever finished...
Make batch itself a service:
https://www.drupal.org/project/drupal/issues/2875151
Create an interface and an initiator:
https://www.drupal.org/project/drupal/issues/2959723
Questions?

More Related Content

PPTX
Modular javascript
PDF
Understanding solid principles
ODP
Drupal Best Practices
PDF
Drupal 8 - Core and API Changes
PDF
Decoupled drupal DcRuhr
ODP
Best Practices For Drupal Developers By Mir Nazim @ Drupal Camp India 2008
PDF
Javascript Best Practices
PPT
Dn D Custom 1
Modular javascript
Understanding solid principles
Drupal Best Practices
Drupal 8 - Core and API Changes
Decoupled drupal DcRuhr
Best Practices For Drupal Developers By Mir Nazim @ Drupal Camp India 2008
Javascript Best Practices
Dn D Custom 1

Similar to Better Drupal 8 Batch Services (20)

PPT
Dn D Custom 1
ODP
Content Staging in Drupal 8
PDF
大規模サイトにおけるユーザーレベルのキャッシュ活用によるパフォーマンスチューニング
ODP
2014 11 20 Drupal 7 -> 8 test migratie
PDF
Drupal Module Development
PDF
Drupal Module Development - OSI Days 2010
PDF
Leveraging the Command Pattern: Enhancing Drupal with Symfony Messenger.pdf
PDF
What is new in java 8 concurrency
PDF
379008-rc217-functionalprogramming
PDF
Camunda BPM 7.2: Tasklist and Javascript Forms SDK (English)
PDF
13th Sep, Drupal 7 advanced training by TCS
PDF
DrupalGap. How to create native application for mobile devices based on Drupa...
PDF
DrupalGap. How to create native application for mobile devices based on Drupa...
PPTX
DrupalCon LA 2015 Review
PDF
Drupal 8: What's new? Anton Shubkin
ODP
Finagle and Java Service Framework at Pinterest
PDF
Drupal 8 improvements for developer productivity php symfony and more
PDF
Advanced Node.JS Meetup
PDF
PHP: 4 Design Patterns to Make Better Code
PDF
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
Dn D Custom 1
Content Staging in Drupal 8
大規模サイトにおけるユーザーレベルのキャッシュ活用によるパフォーマンスチューニング
2014 11 20 Drupal 7 -> 8 test migratie
Drupal Module Development
Drupal Module Development - OSI Days 2010
Leveraging the Command Pattern: Enhancing Drupal with Symfony Messenger.pdf
What is new in java 8 concurrency
379008-rc217-functionalprogramming
Camunda BPM 7.2: Tasklist and Javascript Forms SDK (English)
13th Sep, Drupal 7 advanced training by TCS
DrupalGap. How to create native application for mobile devices based on Drupa...
DrupalGap. How to create native application for mobile devices based on Drupa...
DrupalCon LA 2015 Review
Drupal 8: What's new? Anton Shubkin
Finagle and Java Service Framework at Pinterest
Drupal 8 improvements for developer productivity php symfony and more
Advanced Node.JS Meetup
PHP: 4 Design Patterns to Make Better Code
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
Ad

Recently uploaded (20)

PDF
Project English Paja Jara Alejandro.jpdf
PPTX
PPT_M4.3_WORKING WITH SLIDES APPLIED.pptx
PPTX
Slides, PPTX World Game (s) Eco Economic Epochs.pptx
PPTX
ppt lighfrsefsefesfesfsefsefsefsefserrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrt.pptx
PDF
The Internet -By the Numbers, Sri Lanka Edition
PPTX
AI ad its imp i military life read it ag
PPTX
谢尔丹学院毕业证购买|Sheridan文凭不见了怎么办谢尔丹学院成绩单
PPTX
ENCOR_Chapter_10 - OSPFv3 Attribution.pptx
PPTX
nagasai stick diagrams in very large scale integratiom.pptx
PPTX
Microsoft PowerPoint Student PPT slides.pptx
PDF
KIPER4D situs Exclusive Game dari server Star Gaming Asia
PPTX
Unlocking Hope : How Crypto Recovery Services Can Reclaim Your Lost Funds
PDF
Triggering QUIC, presented by Geoff Huston at IETF 123
PPTX
Parallel & Concurrent ...
PDF
KIPER4D situs Exclusive Game dari server Star Gaming Asia
PPTX
ENCOR_Chapter_11 - ‌BGP implementation.pptx
PDF
PDF document: World Game (s) Great Redesign.pdf
PPT
Transformaciones de las funciones elementales.ppt
PDF
Elements Of Poetry PowerPoint With Sources
PDF
LABUAN4D EXCLUSIVE SERVER STAR GAMING ASIA NO.1
Project English Paja Jara Alejandro.jpdf
PPT_M4.3_WORKING WITH SLIDES APPLIED.pptx
Slides, PPTX World Game (s) Eco Economic Epochs.pptx
ppt lighfrsefsefesfesfsefsefsefsefserrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrt.pptx
The Internet -By the Numbers, Sri Lanka Edition
AI ad its imp i military life read it ag
谢尔丹学院毕业证购买|Sheridan文凭不见了怎么办谢尔丹学院成绩单
ENCOR_Chapter_10 - OSPFv3 Attribution.pptx
nagasai stick diagrams in very large scale integratiom.pptx
Microsoft PowerPoint Student PPT slides.pptx
KIPER4D situs Exclusive Game dari server Star Gaming Asia
Unlocking Hope : How Crypto Recovery Services Can Reclaim Your Lost Funds
Triggering QUIC, presented by Geoff Huston at IETF 123
Parallel & Concurrent ...
KIPER4D situs Exclusive Game dari server Star Gaming Asia
ENCOR_Chapter_11 - ‌BGP implementation.pptx
PDF document: World Game (s) Great Redesign.pdf
Transformaciones de las funciones elementales.ppt
Elements Of Poetry PowerPoint With Sources
LABUAN4D EXCLUSIVE SERVER STAR GAMING ASIA NO.1
Ad

Better Drupal 8 Batch Services

  • 1. Better Drupal 8 Batches Cause “just do it like D7” is like using hand powered a ferry: it gets the job done in the hardest way possible.
  • 2. Batch Overview ● Drupal batch processing is great for doing long running jobs when you can leave a browser open or you need a simple UI to a process. ● It is just as easy for a developer to use as Feeds and more reliable. ● It is built around the best concepts Drupal 5 could give us, the DX is just a little wonky. ● All the advice on D8 batches basically says: “It didn’t change”. But everything else did!
  • 3. Quick batch how-to A typical batch process starts with a form, that generates an array of tasks, which reference PHP functions that implement callback_batch_operation(), and finally calls function that implements callback_batch_finish(). callback_batch_operation() each call to is passed a collection of parameters followed by an array called $context that allows for intra and inter task messages. Any given task can be called once, or a thousand times. Task runs should be short so Drupal can reboot strap as needed. callback_batch_finish() is called when everything is done, or fails, to report outcome.
  • 4. Why do we need a new interface? We don’t. Then why are we here? The current solution works well enough to drive the Drupal 8 installer, bulk operations, and lots of other things.
  • 5. Why do we want a new interface? ● All the advice on D8 batches basically says: “It didn’t change”. But everything else did! ● The batch array definitions are obscure and hard to remember. ● Current patterns require either inserting procedural code into your project or your create a class with a bunch of static functions. ○ Both limit your ease of access to other Drupal services since you are pulling them into a global or static context. ● Having a service that can run as a more standard service it makes your new code more standard with everything else.
  • 6. Introducing Batch Service Interface Sandbox Project: https://www.drupal.org/sandbox/acrosman/3025562 Provides an interface that defines the service, an abstract class of helper functions to do all the static work, and a silly example module to prove it works. All you have to do is define the service, define the form, provide your list of tasks (functions in the class), and let it run. It handles array prep for batch, instantiating services, and related elements.
  • 7. Simple form with simple code public function submitForm(array &$form, FormStateInterface $form_state) { $data = [ 'message_count' => $form_state->getValue('message_count'), ]; $batch = $this->exampleBatchService->generateBatchJob($data); batch_set($batch); }
  • 8. Generate the batch job public function generateBatchJob($data) { $ops = []; for ($i = 0; $i < $data['message_count']; $i++ ) { $ops[] = [ 'logMessage' => ['MessageIndex' => $i + 1], ]; } return $this->prepBatchArray($this->t('Replace Users'), $this->t('Starting Batch Processing'), $ops); }
  • 9. Define Worker Method public function logMessage($data, &$context) { // We could do something interesting here. $this->logger->info($this->getRandomMessage()); if (!isset($context['results']['message_count'])) { $context['results']['message_count'] = 0; } $context['results']['message_count']++; }
  • 10. And we’re done... public function doFinishBatch($success, $results, $operations) { drupal_set_message($this->t('Logged %count quotes', ['%count' => $results['message_count']])); }
  • 11. Okay there is a little funkiness class ExampleBatchService extends AbstractBatchService { /** * Must be set in child classes to be the service name so the service can * bootstrap itself. * * @var string */ protected static $serviceName = 'batch_example.example_batch';
  • 12. Let’s see it go...then look at the code...
  • 13. Related Core Effort These will be better, if they are ever finished... Make batch itself a service: https://www.drupal.org/project/drupal/issues/2875151 Create an interface and an initiator: https://www.drupal.org/project/drupal/issues/2959723