Skip to content

Commit b01a19d

Browse files
committed
Add support to handle external stop signals in ChunkOrientedStep
1 parent d18dc01 commit b01a19d

File tree

1 file changed

+21
-14
lines changed

1 file changed

+21
-14
lines changed

spring-batch-core/src/main/java/org/springframework/batch/core/step/item/ChunkOrientedStep.java

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
import org.apache.commons.logging.LogFactory;
2020
import org.jspecify.annotations.Nullable;
2121

22-
import org.springframework.batch.core.BatchStatus;
23-
import org.springframework.batch.core.ExitStatus;
2422
import org.springframework.batch.core.job.JobInterruptedException;
2523
import org.springframework.batch.core.listener.ChunkListener;
2624
import org.springframework.batch.core.listener.CompositeChunkListener;
@@ -309,18 +307,8 @@ protected void close(ExecutionContext executionContext) throws Exception {
309307

310308
@Override
311309
protected void doExecute(StepExecution stepExecution) throws Exception {
312-
stepExecution.getExecutionContext().put(STEP_TYPE_KEY, this.getClass().getName());
313-
while (this.chunkTracker.moreItems()) {
314-
// check interruption policy before processing next chunk
315-
try {
316-
this.interruptionPolicy.checkInterrupted(stepExecution);
317-
}
318-
catch (JobInterruptedException exception) {
319-
stepExecution.setTerminateOnly();
320-
stepExecution.setStatus(BatchStatus.STOPPED);
321-
stepExecution.setExitStatus(ExitStatus.STOPPED);
322-
return;
323-
}
310+
stepExecution.getExecutionContext().put(STEP_TYPE_KEY, this.getClass().getName());
311+
while (this.chunkTracker.moreItems() && !interrupted(stepExecution)) {
324312
// process next chunk in its own transaction
325313
this.transactionTemplate.execute(new TransactionCallbackWithoutResult() {
326314
@Override
@@ -355,6 +343,25 @@ protected void doInTransactionWithoutResult(TransactionStatus status) {
355343
}
356344
}
357345

346+
/*
347+
* Check if the step has been interrupted either internally via user defined policy or
348+
* externally via job operator. This will be checked at chunk boundaries.
349+
*/
350+
private boolean interrupted(StepExecution stepExecution) {
351+
// check internal interruption via user defined policy
352+
try {
353+
this.interruptionPolicy.checkInterrupted(stepExecution);
354+
}
355+
catch (JobInterruptedException exception) {
356+
return true;
357+
}
358+
// check external interruption via job operator
359+
if (stepExecution.isTerminateOnly()) {
360+
return true;
361+
}
362+
return false;
363+
}
364+
358365
private Chunk<I> read(StepContribution contribution) throws Exception {
359366
Chunk<I> chunk = new Chunk<>();
360367
for (int i = 0; i < chunkSize; i++) {

0 commit comments

Comments
 (0)