spring-projects / spring-batch

Spring Batch is a framework for writing batch applications using Java and Spring
http://projects.spring.io/spring-batch/
Apache License 2.0
2.74k stars 2.36k forks source link

Add StepExecution parameter to StoppableTasklet.stop() #4703

Open andrianov17 opened 2 weeks ago

andrianov17 commented 2 weeks ago

Currently, StoppableTasklet.stop() doesn't take any parameters. So, from within tasklet it is impossible to distinguish which exactly step execution is requested to stop out of multiple job executions running. This is important when some external request needs to be executed from StoppableTasklet.stop().

Looking into SimpleJobOperator.stop(long executionId) implementation, it looks very straightforward to implement this request - just pass stepExecution to the tasklet stop() method:

@Override
    public boolean stop(long executionId) throws NoSuchJobExecutionException, JobExecutionNotRunningException {

        JobExecution jobExecution = findExecutionById(executionId);
        // Indicate the execution should be stopped by setting it's status to
        // 'STOPPING'. It is assumed that
        // the step implementation will check this status at chunk boundaries.
        BatchStatus status = jobExecution.getStatus();
        if (!(status == BatchStatus.STARTED || status == BatchStatus.STARTING)) {
            throw new JobExecutionNotRunningException(
                    "JobExecution must be running so that it can be stopped: " + jobExecution);
        }
        jobExecution.setStatus(BatchStatus.STOPPING);
        jobRepository.update(jobExecution);

        try {
            Job job = jobRegistry.getJob(jobExecution.getJobInstance().getJobName());
            if (job instanceof StepLocator) {// can only process as StepLocator is the
                                                // only way to get the step object
                // get the current stepExecution
                for (StepExecution stepExecution : jobExecution.getStepExecutions()) {
                    if (stepExecution.getStatus().isRunning()) {
                        try {
                            // have the step execution that's running -> need to 'stop' it
                            Step step = ((StepLocator) job).getStep(stepExecution.getStepName());
                            if (step instanceof TaskletStep) {
                                Tasklet tasklet = ((TaskletStep) step).getTasklet();
                                if (tasklet instanceof StoppableTasklet) {
                                    StepSynchronizationManager.register(stepExecution);
                                    ((StoppableTasklet) tasklet).stop(**stepExecution**);
                                    StepSynchronizationManager.release();
                                }
                            }
                        }

Thank you in advance!

HyunSangHan commented 2 days ago

Can I work on this issue?

HyunSangHan commented 1 day ago

I have submitted a PR!: https://github.com/spring-projects/spring-batch/pull/4715