-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Terminates the job if a flag is set on afterStep #4455
base: main
Are you sure you want to change the base?
Conversation
533cdf9
to
5c5a70d
Compare
Thank you for opening this PR. I am not sure "isTerminateOnly" was designed to be used in a step execution listener. My thinking is that in the There is a key difference between a Here is a quick example: import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepExecutionListener;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.support.JdbcTransactionManager;
import javax.sql.DataSource;
@Configuration
@EnableBatchProcessing
public class HelloWorldJobConfiguration {
public static void main(String[] args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(HelloWorldJobConfiguration.class);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
Job job = context.getBean(Job.class);
jobLauncher.run(job, new JobParameters());
}
@Bean
public Step step1(JobRepository jobRepository, JdbcTransactionManager transactionManager) {
return new StepBuilder("step1", jobRepository)
.tasklet((contribution, chunkContext) -> {
System.out.println("Hello");
return RepeatStatus.FINISHED;
}, transactionManager)
.listener(new StepExecutionListener() {
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
stepExecution.setTerminateOnly();
return stepExecution.getExitStatus();
}
})
.build();
}
@Bean
public Step step2(JobRepository jobRepository, JdbcTransactionManager transactionManager) {
return new StepBuilder("step2", jobRepository).tasklet((contribution, chunkContext) -> {
System.out.println("world!");
return RepeatStatus.FINISHED;
}, transactionManager).build();
}
@Bean
public Job job(JobRepository jobRepository, Step step1, Step step2) {
return new JobBuilder("job", jobRepository)
.start(step1)
.next(step2)
.build();
}
// infra beans
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.addScript("/org/springframework/batch/samples/common/business-schema-hsqldb.sql")
.generateUniqueName(true)
.build();
}
@Bean
public JdbcTransactionManager transactionManager(DataSource dataSource) {
return new JdbcTransactionManager(dataSource);
}
} In this case, step2 runs even if step1 was flagged as terminateOnly. However, if I only change the job type to
Do you see the difference?
BTW, I find that stopping a job with a listener is implicit rather than explicit. The more explicit way would be to create a clear execution flow through the Java DSL or the XML namespace. |
As-is : Even if the terminateOnly flag is set on afterStep, It is ignored and the next step is executed. There is no way to terminate a job gracefully without using the
on(ExitStatus)
method when building the job.To-be : If the terminateOnly flag is set, the job terminates gracefully.
It looks similar to #1213 but It's different.
If developers want to explicitly terminate a job, they should be able to do so.