spring-projects/spring-batch

Add StepExecution parameter to StoppableTasklet.stop()

Opened this issue · 2 comments

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!

Can I work on this issue?

I have submitted a PR!: #4715