1

I was reading the Spring Batch documentation when I came across the fact that we would have to use a different implementation of the TaskExecutor interface (The Asynchronous version) if we would efficiently have to run batch jobs from a web container.

I am assuming that an Http request would trigger the batch job. And as I understand it, when the client launches the job via the run method of the JobLauncher interface, the client has to wait for the JobExecution object to be returned back and since a typical batch job would run for hours at an end, this might not be very feasible if the jobs are executed synchronously. Now, the AsyncTaskExecutor would execute each step in separate threads and would return the JobExecution object immediately with an UNKNOWN status.

Firstly, can someone please explain to me, how this works from a client-server connection perspective? In each case, would the client not wait for the batch to be finished before he terminates the session? Or, would the client not know about the exit status of the batch job? Is the whole problem to do with the connection having to remain till the batch ends?

As an example, say the client has a web page which sends an HTTP get request, which is served by a servlet's doget method. This method calls the run method of the job launcher. This method will return the JobExecution object. And the rest of the story is as above.

Thanks, Aditya.

Premraj
  • 72,055
  • 26
  • 237
  • 180
Aditya
  • 47
  • 1
  • 7

2 Answers2

4

It depends a bit on what your servlet does after it has called the run method and received the JobExecution object in return. I will assume that the doget method just returns after run is called.

If you do not use an asynchronous executor the call to the run method on the job launcher will be executed synchronously. That is, the call will wait until the batch job is done and the JobExecution object is returned. From a connection perspective, the client's HTTP connection will remain open during the entire batch job. The HTTP connection will be closed when the servlet's doGet method returns (or before if some kind of timeout is encountered on some level, e.g. firewall or a socket read timeout).

If you do use a asynchronous executor the call to the run method will return immediately. The doGet method will return after that, the HTTP response will be sent to the client and the connection will be closed (assuming there is not HTTP keep-alive).

K Erlandsson
  • 13,408
  • 6
  • 51
  • 67
  • Thanks for your response. How will the client get to know about the status of the batch execution in this case? Or is it impossible to know in this scenario? – Aditya Oct 05 '11 at 09:55
  • You will have to solve that in a custom way. A typical way would be to return some kind of batch identifier to the client, which the client then can use to query the status of the batch. – K Erlandsson Oct 05 '11 at 10:51
  • I do not understand this, the AsyncTaskExecutor uses a **multi-threaded** approach and hence must be spawning several threads for running the job. Now, the main thread (in which the run method is called) will exit, implying the connection is closed. But this means the process also ends right? That would mean all the threads of the process would end too? Isn't that true? How are the batch jobs still running when the connection is closed? [The process ends, that is]. Thanks for your responses. – Aditya Oct 05 '11 at 11:55
  • If the process ends, then the batch jobs will not be running, in that you are correct. So you need some way to keep the process running. If you start the batch using a servlet, then you probably are running in a web container, which will not exit just because the request connection is closed and the request handling thread exits. – K Erlandsson Oct 05 '11 at 12:10
  • @Aditya there are standard ways for you to retrieve status of job execution in Spring Batch, WITHOUT need of any "custom way". Depending on your need, you may simply need to query the job execution from `JobExplorer`, `JobOperator` or even `JobExecutionDao` etc (it should be `JobExplorer` 99% of time though) – Adrian Shum Jun 19 '17 at 02:03
0

Running Jobs from within a Web Container

Usually jobs are launched from the command-line. However, there are many cases where launching from an HttpRequest is a better option. Many such use cases include reporting, ad-hoc job running, and web application support. Because a batch job by definition is long running, the most important concern is ensuring to launch the job asynchronously:

enter image description here

Here Spring MVC controller launches a Job using a JobLauncher that has been configured to launch asynchronously, which immediately returns a JobExecution. The Job will likely still be running, however, this nonblocking behaviour allows the controller to return immediately, which is required when handling an HttpRequest.

An example is below:

@Controller
public class JobLauncherController {

    @Autowired
    JobLauncher jobLauncher;

    @Autowired
    Job job;

    @RequestMapping("/jobLauncher.html")
    public void handle() throws Exception{
        jobLauncher.run(job, new JobParameters());
    }
}

source

Premraj
  • 72,055
  • 26
  • 237
  • 180