From 0826db6ae71a7d3427f92ab7e499406707e31709 Mon Sep 17 00:00:00 2001 From: dsyer Date: Thu, 16 Oct 2008 15:44:05 +0000 Subject: [PATCH] IN PROGRESS - issue BATCH-677: Partition SPI. Javadocs --- .../core/partition/StepExecutionSplitter.java | 6 ++--- .../core/partition/support/Partitioner.java | 20 +++++++++++++++- .../partition/support/SimplePartitioner.java | 9 +++++++ .../support/SimpleStepExecutionSplitter.java | 24 ++++++++++++++++++- .../support/StepExecutionAggregator.java | 20 ++++++++++++++++ 5 files changed, 74 insertions(+), 5 deletions(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/partition/StepExecutionSplitter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/partition/StepExecutionSplitter.java index f49a36132..c9f5b9694 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/partition/StepExecutionSplitter.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/partition/StepExecutionSplitter.java @@ -8,7 +8,7 @@ import org.springframework.batch.core.StepExecution; /** * Strategy interface for generating input contexts for a partitioned step - * execution. + * execution independent from the fabric they are going to run on. * * @author Dave Syer * @@ -33,8 +33,8 @@ public interface StepExecutionSplitter { * * On a restart clients of the {@link StepExecutionSplitter} should expect * it to reconstitute the state of the last failed execution and only return - * those executions that need to be restarted. Thus the grid size hint - * should be ignored on a restart. + * those executions that need to be restarted. Thus the grid size hint will + * be ignored on a restart. * * @param stepExecution the {@link StepExecution} to be partitioned. * @param gridSize a hint for the splitter if the size of the grid is known diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/Partitioner.java b/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/Partitioner.java index 57c59a24d..7245e9cbd 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/Partitioner.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/Partitioner.java @@ -4,8 +4,26 @@ import java.util.Map; import org.springframework.batch.item.ExecutionContext; +/** + * Central strategy interface for creating input parameters for a partitioned + * step in the form of {@link ExecutionContext} instances. The usual aim is to + * create a set of distinct input values, e.g. a set of non-overlapping primary + * key ranges, or a set of unique filenames. + * + * @author Dave Syer + * + */ public interface Partitioner { + /** + * Create a set of distinct {@link ExecutionContext} instances together with + * a unique identifier for each one. The identifiers should be short, + * mnemonic values, and only have to be unique within the return value (e.g. + * use an incrementer). + * + * @param gridSize the size of the map to return + * @return a map from identifier to input parameters + */ Map partition(int gridSize); - + } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/SimplePartitioner.java b/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/SimplePartitioner.java index 8755532db..f9d052fa7 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/SimplePartitioner.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/SimplePartitioner.java @@ -5,6 +5,15 @@ import java.util.Map; import org.springframework.batch.item.ExecutionContext; +/** + * Simplest possible implementation of {@link Partitioner}. Just creates a set + * of empty {@link ExecutionContext} instances, and labels them as + * {partition0, partition1, ..., partitionN}, where N is the grid + * size. + * + * @author Dave Syer + * + */ public class SimplePartitioner implements Partitioner { private static final String PARTITION_KEY = "partition"; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/SimpleStepExecutionSplitter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/SimpleStepExecutionSplitter.java index bfe37b152..626120db2 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/SimpleStepExecutionSplitter.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/SimpleStepExecutionSplitter.java @@ -14,6 +14,19 @@ import org.springframework.batch.core.partition.StepExecutionSplitter; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.item.ExecutionContext; +/** + * Generic implementation of {@link StepExecutionSplitter} that delegates to a + * {@link Partitioner} to generate {@link ExecutionContext} instances. Takes + * care of restartability and identifying the step executions from previous runs + * of the same job. The generated {@link StepExecution} instances have names + * that identify them uniquely in the partition. The name is constructed from a + * base (name of the target step) plus a suffix taken from the + * {@link Partitioner} identifiers, separated by a colon, e.g. + * {step1:partition0, step1:partition1, ...}. + * + * @author Dave Syer + * + */ public class SimpleStepExecutionSplitter implements StepExecutionSplitter { private static final String STEP_NAME_SEPARATOR = ":"; @@ -30,6 +43,15 @@ public class SimpleStepExecutionSplitter implements StepExecutionSplitter { this(jobRepository, step, new SimplePartitioner()); } + /** + * Construct a {@link SimpleStepExecutionSplitter} from its mandatory + * properties. + * + * @param jobRepository the {@link JobRepository} + * @param step the target step (a local version of it) + * @param partitioner a {@link Partitioner} to use for generating input + * parameters + */ public SimpleStepExecutionSplitter(JobRepository jobRepository, Step step, Partitioner partitioner) { this.jobRepository = jobRepository; this.step = step; @@ -95,7 +117,7 @@ public class SimpleStepExecutionSplitter implements StepExecutionSplitter { boolean isRestart = (lastStepExecution != null && lastStepExecution.getStatus() != BatchStatus.COMPLETED) ? true : false; - + if (isRestart) { stepExecution.setExecutionContext(lastStepExecution.getExecutionContext()); } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/StepExecutionAggregator.java b/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/StepExecutionAggregator.java index eaa49b435..39a73d557 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/StepExecutionAggregator.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/StepExecutionAggregator.java @@ -4,10 +4,30 @@ import java.util.Collection; import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.StepExecution; +import org.springframework.batch.repeat.ExitStatus; import org.springframework.util.Assert; +/** + * Convenience class for aggregating a set of {@link StepExecution} instances + * into a single result. + * + * @author Dave Syer + * + */ public class StepExecutionAggregator { + /** + * Take the inputs and aggregate certain fields, putting the aggregates into + * the result. The aggregated fields are + * + * + * @param result the result to overwrite + * @param executions the inputs + */ public void aggregate(StepExecution result, Collection executions) { Assert.notNull(result, "To aggregate into a result it must be non-null."); if (executions == null || executions.isEmpty()) {