Being ‘unstoppable’ – a Batchlets tale

How to stop a JBatch Batch

JSR-352 (JBatch) is a great specification. It takes care of many situations a user don’t think about most times. For example how to stop a Batch. But sometimes it cannot relief you from putting some brain into it.

How to trigger a Batch stop?

The JobOperator has a method to stop a specific execution: JobOperator#stop(long executionId).

Of course the JobOperator will not immediately kill the worker thread with this batch but tries to gracefully shut down the Batch.

Stopping a ‘Chunk Step’

First, what is a ‘Chunk’? A chunk is a batch <step> which consists of an ItemReader an optional ItemProcessor and an ItemWriter. A ‘chunk’ defines the transaction size of the processing. Let’s consider a chunk-size of 10. This means that our step processes 10 items and then commits all of them in a single commit.

The processing order is as following
ItemReader, ItemProcessor, ItemReader, ItemProcessor,… until we did read and process our 10 items. After that all the 10 items will get handed over to the ItemWriter to store them somewhere. After that a commit happens and the loop starts over with the next items.

If you call JobOperator#stop(executionId) for a Chunk Step then the loop which invokes the ItemReader, ItemProcessor and ItemWriter will continue with reading and processing the current Item and then hand over all the currently chained Items to the ItemWriter. After that the loop exits gracefully.

That’s nice and clean! But what about Batchlets?

Stopping a ‘Batchlet’

There is a good reason why I write this post today. In the last few weeks we had a few Batchlets which didn’t behave ‘nice’ to our ops team. Those beasts didn’t want to stop working! Of course the problem only occurred in production and not in all the tests done before. Simply because in production we have millions of items to process whereas in the test they just fed in a a few thousand items.

So why didn’t those Batchlets stop?

First we have to understand what a Batchlet is. Opposite to a Chunk Step a Batchlet is a ‘do-it-yourself’ thingy. The JBatch runtime really hands over all the control to your code. It doesn’t even do Transactions for you! It is really all in your hands. Usually such a batchlet contains a processing loop as well:

public class MyBatchlet extends AbstractBatchlet {
  @Override
  public String process() throws Exception {
    List items = readAllItemsToProcess();
    for (MyItem item : items) {
      processAndStoreMyItem();
    }
    return "OK";
  }
}

That’s nice…. but won’t stop for you…

So what is missing? Yes, AbstractBatchlet implements an empty stop() method. And this is often a bad idea…

Our code should better look somehow like the following:

public class MyBatchlet implements Batchlet {
  private volatile boolean shouldStop = false;

  @Override
  public void stop() {
    shouldStop = true;
  }

  @Override
  public String process() throws Exception {
    List items = readAllItemsToProcess();
    for (MyItem item : items) {
      processAndStoreMyItem();
      if (shouldStop) {
        return "STOPPING";
      }
    }
    return "OK";
  }
}

There are a few important details:
1.) the boolean shouldStop field really needs to be volatile. That is because the stop() method gets called from a different thread and otherwise the new value might not be visible to the worker thread. Read up more on volatile over at the excellent Angelika Langers Java Memory Model talk.

2.) I’m thinking about preventing the usage of “extends AbstractBatchlet” via a checkstyle rule. It’s actually not worth having this AbstractBatchlet. People should be aware that they missed the stop() functionality!

Advertisements

About struberg
I'm an Apache Software Foundation member blogging about Java, µC, TheASF, OpenWebBeans, Maven, MyFaces, CODI, GIT, OpenJPA, TomEE, DeltaSpike, ...

One Response to Being ‘unstoppable’ – a Batchlets tale

  1. Pingback: Java Weekly 41/15: Java Puzzle, Java Legend ebook, Batchlets

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: