Overview
A method to execute the job asynchronously in Web container is explained.
The usage method of this function is same in the chunk model as well as tasklet model.
Web application that contains a job is deployed in a Web container
and the job is executed based on information of sent request.
Since one thread is allocated for each job execution and operation is run in parallel,
it can be executed independent of processes for other jobs and requests.
TERASOLUNA Batch 5.x does not offer implementation for asynchronous execution (Web container).
Only methods of implementation will be provided in this guideline.
This is because the start timing of the Web application is various such as HTTP / SOAP / MQ,
and hence it is determined that the implementation should be appropriately done by the user.
-
A Web container is required besides the application.
-
Besides implementation of job, required Web application and client are separately implemented according to the operation requirements.
-
Execution status and results of the job is entrusted to
JobRepository
. Further, a permanently residing database is used instead of in-memory database to enable execution status and results of job to be referred fromJobRepository
even after stopping Web container.
It is same as Asynchronous execution (DB polling) - Overview.
Difference with asynchronous execution (DB polling)
On the architecture front, immediacy at the time of asynchronous execution and presence or absence of request management table are different. |
Architecture
Asynchronous jobs by using this method are operated as applications (war) deployed on the Web container, however, the job itself runs asynchronously (another thread) from the request processing of Web container.
-
Web client requests Web container to execute the job.
-
JobController
asksJobOperator
of Spring Batch to start the execution of the job. -
Execute the job asynchronously by using
ThreadPoolTaskExecutor
. -
Return a job execution ID (
job execution id
) for uniquely identifying an executed target job. -
JobController
returns a response including job execution ID for the Web client. -
Execute target job.
-
Job results are reflected in
JobRepository
.
-
-
Job
returns execution results. It cannot be notified directly to the client.
-
Web client sends job execution ID and
JobController
to Web container. -
JobController
asksJobExplorer
for execution results of job by using a job execution ID. -
JobExplorer
returns job execution results. -
JobController
returns a response for Web client.-
Set Job execution ID in the response.
-
After receiving a request using Web container, operation is synchronised with the request processing till job execution ID payout, however subsequent job execution is performed asynchronously in a thread pool different from that of Web container.+ As long as the query is not sent again by sending a request, it signifies that execution status of asynchronous job cannot be detected on Web client side.
Hence, the request should be sent once at the time of "running a job" on the Web client side during one job execution.
When "confirmation of results" is necessary, request must be sent once again to the Web container.
Abnormality detection which looks different from first "running a job" will be explained later in
About detection of abnormality occurrence at the time of running a job.
Job execution status can be checked by referring direct RDBMS, by using |
About handling job execution ID (job execution id)
Job execution ID generates a different sequence value for each job even though job and job parameters are identical. |
About detection of abnormality occurrence at the time of running a job
After sending a job run request from Web client, abnormality detection appearance varies along with job execution ID payout.
-
Abnormality can be detected immediately by the response at the time of running a job
-
Job to be activated does not exist.
-
Invalid job parameter format.
-
-
After running a job, queries regarding job execution status and results for Web container are necessary
-
Job execution status
-
Job start failure due to depletion of thread pool used in asynchronous job execution
-
"Job running error" can be detected as an exception occurring in Spring MVC controller. Since the explanation is omitted here, refer Implementation of exception handling of TERASOLUNA Server 5.x Development Guideline described separately. Further, input check of the request used as a job parameter is performed in the Spring MVC controller as required. |
Job start failure occurring due to depletion of thread pool cannot be caught at the time of running a job.
Job start failure due to depletion of thread pool is not generated from
|
Application configuration of asynchronous execution (Web container)
The function is same as Asynchronous execution (DB polling) and use
async
and AutomaticJobRegistrar
of Spring profile as a configuration specific to asynchronous execution.
On the other hand, prior knowledge and some specific settings are required in order to use these functions asynchronously (Web container).
Refer ApplicationContext configuration.
For configuration methods of basic async
profile and AutomaticJobRegistrar
,
How to implement applications using asynchronous execution (Web container) will be described later.
ApplicationContext configuration
As described above, multiple application modules are included as application configuration of asynchronous execution (Web container).
It is necessary to understand respective application contexts, types of Bean definitions and their relationships.
ApplicationContext
of batch application is incorporated in the context, in ApplicationContext
during asynchronous execution (Web container).
Individual job contexts are modularised from Web context using AutomaticJobRegistrar
and
it acts as a sub-context of Web context.
Bean definition file which constitute respective contexts are explained.
Sr. No. | Description |
---|---|
(1) |
Common Bean definition file. |
(2) |
Bean definition file which is always imported from job Bean definitions. |
(3) |
Bean definition file created for each job. |
(4) |
It is read from |
(5) |
It acts as a parent context shared within the Web application by using |
How to use
Here, explanation is given using TERASOLUNA Server Framework for Java (5.x), as an implementation example of Web application.
Kindly remember that only explanation is offered and TERASOLUNA Server 5.x is not a necessary requirement of asynchronous execution (Web container).
Overview of implementation of application by asynchronous execution (Web container)
Explanation is given based on following configuration.
-
Web application project and batch application project are independent and a batch application is referred from a web application.
-
war file generated from Web application project contains jar file generated from batch application project
-
Implementation of asynchronous execution is performed in accordance with Architecture wherein Spring
MVC controller in the Web application starts the job by using JobOperator
.
About isolation of Web/batch application project
Final deliverable of application build is a war file of Web application, however,
a development project should be implemented by separating Web/batch applications. |
Web/batch development is explained now assuming the use of 2 components below.
-
Batch application project by TERASOLUNA Batch 5.x
-
Web application project by TERASOLUNA Server 5.x
For how to create a batch application project and how to implement a basic job, refer How to create a project, Creation of chunk model job, Creation of tasklet model job.
Here, we will focus on starting a batch application from a Web application.
Here, explanation is given by creating a batch application project, by using Maven archetype:generate.
Name | Value |
---|---|
groupId |
org.terasoluna.batch.sample |
archetypeId |
asyncbatch |
version |
1.0-SNAPSHOT |
package |
org.terasoluna.batch.sample |
A job registered from the beginning for a blank project is used for convenience of explanation.
Name | Description |
---|---|
Job name |
job01 |
Job parameter |
param1=value1 |
Precautions for asynchronous execution (Web container) job design
Individual jobs are completed in a short period of time as a characteristic of asynchronous execution (Web container)
and are operated in a stateless manner on the Web container. |
Create a Web application as a state wherein a jar file including a job implementation can be created.
How to implement a Web application is explained by using a blank project offered by TERASOLUNA Server 5.x. For details, refer TERASOLUNA Server 5.x Development Guideline Creating a development project for Web application.
Here, similar to asynchronous execution application project, explanation is given below creating with the following names.
Name | Value |
---|---|
groupId |
org.terasoluna.batch.sample |
archetypeId |
asyncapp |
version |
1.0-SNAPSHOT |
package |
org.terasoluna.batch.sample |
About naming of groupId
Although naming a project is optional, when a batch application as a Maven multiproject is considered as a sub-module,
it is easy to manage if |
Various settings
Edit pom.xml and include batch application as a part of Web application.
Batch application is registered in NEXUS or Maven local repository as |
<project>
<!-- omitted -->
<modules>
<module>asyncapp-domain</module>
<module>asyncapp-env</module>
<module>asyncapp-initdb</module>
<module>asyncapp-web</module>
<module>asyncapp-selenium</module>
<module>asyncbatch</module> <!-- (1) -->
</modules>
</project>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.terasoluna.batch.sample</groupId> <!-- (2) -->
<artifactId>asyncbatch</artifactId>
<version>1.0-SNAPSHOT</version> <!-- (2) -->
<!-- (1) -->
<parent>
<groupId>org.terasoluna.batch.sample</groupId>
<artifactId>asyncapp</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<!-- omitted -->
</project>
Sr. No. | Description |
---|---|
(1) |
Add settings for considering the Web application as a parent and batch application as a child. |
(2) |
Delete unnecessary description with deletion of child or sub-module. |
Add a batch application as a dependent library of Web application.
<project>
<!-- omitted -->
<dependencies>
<!-- (1) -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>asyncbatch</artifactId>
<version>${project.version}</version>
</dependency>
<!-- omitted -->
</dependencies>
<!-- omitted -->
</project>
Sr. No. | Description |
---|---|
(1) |
Add a batch application as a dependent library of Web application. |
Implementation of Web application
Here, a RESTful Web service is created as a Web application using TERASOLUNA Server 5.x Development Guideline as a reference below.
Setting for enabling Spring MVC component which is necessary for RESTful Web Service
Web application settings
At first, add, delete and edit various configuration files from the blank project of Web application.
For the explanation, an implementation which use RESTful Web Service as an implementation status of batch application is given. |
<!-- omitted -->
<!-- (1) -->
<import resource="classpath:META-INF/spring/launch-context.xml"/>
<bean id="jsonMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"
p:objectMapper-ref="objectMapper"/>
<bean id="objectMapper"
class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="dateFormat">
<bean class="com.fasterxml.jackson.databind.util.StdDateFormat"/>
</property>
</bean>
<mvc:annotation-driven>
<mvc:message-converters register-defaults="false">
<ref bean="jsonMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
<mvc:default-servlet-handler/>
<!-- (2) -->
<context:component-scan base-package="org.terasoluna.batch.sample.app.api"/>
<!-- (3) -->
<bean class="org.springframework.batch.core.configuration.support.AutomaticJobRegistrar">
<property name="applicationContextFactories">
<bean class="org.springframework.batch.core.configuration.support.ClasspathXmlApplicationContextsFactoryBean">
<property name="resources">
<list>
<value>classpath:/META-INF/jobs/**/*.xml</value>
</list>
</property>
</bean>
</property>
<property name="jobLoader">
<bean class="org.springframework.batch.core.configuration.support.DefaultJobLoader"
p:jobRegistry-ref="jobRegistry"/>
</property>
</bean>
<!-- (4) -->
<task:executor id="taskExecutor" pool-size="3" queue-capacity="10"/>
<!-- (5) -->
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher"
p:jobRepository-ref="jobRepository"
p:taskExecutor-ref="taskExecutor"/>
<!-- omitted -->
<!-- omitted -->
<servlet>
<servlet-name>restApiServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- (6) -->
<param-value>classpath*:META-INF/spring/spring-mvc-rest.xml</param-value>
</init-param>
<!-- (7) -->
<init-param>
<param-name>spring.profiles.active</param-name>
<param-value>async</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>restApiServlet</servlet-name>
<url-pattern>/api/v1/*</url-pattern>
</servlet-mapping>
<!-- omitted -->
Sr. No. | Description |
---|---|
(1) |
Import |
(2) |
Describe package for dynamically scanning the controller. |
(3) |
Describe a Bean definition of |
(4) |
Define Further, multiplicity of threads which can be operated in parallel can be specified. |
(5) |
Override |
(6) |
Specify |
(7) |
Specify |
When async profile is not specified
In this case, a Bean defined in |
Thread pool sizing
When the upper limit of thread pool is in excess, an enormous amount of jobs run in parallel resulting
in deterioration of entire thread pool.
Sizing should be done and appropriate upper value must be determined. Further, a separate request must be sent from Web client for checking occurrence of |
Here, "Running a job" and "Job status check" are defined as 2 examples of requests used in REST API.
Sr.No. | API | Path | HTTP method | Request / Response | Message format | Message details |
---|---|---|---|---|---|---|
(1) |
Running a job |
/api/v1/job/Job name |
POST |
Request |
JSON |
Job parameter |
Response |
JSON |
Job execution ID |
||||
(2) |
Job execution status check |
/api/v1/job/Job execution ID |
GET |
Request |
N/A |
N/A |
Response |
JSON |
Job execution ID |
Implementation of JavaBeans used in Controller
Create following 3 classes that are returned to REST client as JSON message.
-
Job run operation
JobOperationResource
-
Job execution status
JobExecutionResource
-
Step execution status
StepExecutionResource
These classes are implementations for reference except for job execution ID (job execution id
) of JobOperationResource
and implementation of field is optional.
// asyncapp/asyncapp-web/src/main/java/org/terasoluna/batch/sample/app/api/jobinfo/JobOperationResource.java
package org.terasoluna.batch.sample.app.api.jobinfo;
public class JobOperationResource {
private String jobName = null;
private String jobParams = null;
private Long jobExecutionId = null;
private String errorMessage = null;
private Exception error = null;
// Getter and setter are omitted.
}
// asyncapp/asyncapp-web/src/main/java/org/terasoluna/batch/sample/app/api/jobinfo/JobExecutionResource.java
package org.terasoluna.batch.sample.app.api.jobinfo;
// omitted.
public class JobExecutionResource {
private Long jobExecutionId = null;
private String jobName = null;
private Long stepExecutionId = null;
private String stepName = null;
private List<StepExecutionResource> stepExecutions = new ArrayList<>();
private String status = null;
private String exitStatus = null;
private String errorMessage;
private List<String> failureExceptions = new ArrayList<>();
// Getter and setter are omitted.
}
// asyncapp/asyncapp-web/src/main/java/org/terasoluna/batch/sample/app/api/jobinfo/StepExecutionResource.java
package org.terasoluna.batch.sample.app.api.jobinfo;
public class StepExecutionResource {
private Long stepExecutionId = null;
private String stepName = null;
private String status = null;
private List<String> failureExceptions = new ArrayList<>();
// Getter and setter are omitted.
}
Implementation of controller
A controller of RESTful Web Service is implemented by using @RestController
.
in order to simplify, JobOperator
is injected in the controller and running a job and execution status are fetched.
Of course, JobOperator
can also be started by using Service from the controller in accordance with TERASOLUNA Server 5.x.
About job parameters that are passed at the time of running a job
The job parameter passed in the second argument of This is same as the method of specifying job parameters in Asynchronous execution (DB polling). |
// asyncapp/asyncapp-web/src/main/java/org/terasoluna/batch/sample/app/api/JobController.java
package org.terasoluna.batch.sample.app.api;
// omitted
// (1)
@RequestMapping("job")
@RestController
public class JobController {
// (2)
@Inject
JobOperator jobOperator;
// (2)
@Inject
JobExplorer jobExplorer;
@RequestMapping(value = "{jobName}", method = RequestMethod.POST)
public ResponseEntity<JobOperationResource> launch(@PathVariable("jobName") String jobName,
@RequestBody JobOperationResource requestResource) {
JobOperationResource responseResource = new JobOperationResource();
responseResource.setJobName(jobName);
try {
// (3)
Long jobExecutionId = jobOperator.start(jobName, requestResource.getJobParams());
responseResource.setJobExecutionId(jobExecutionId);
return ResponseEntity.ok().body(responseResource);
} catch (NoSuchJobException | JobInstanceAlreadyExistsException | JobParametersInvalidException e) {
responseResource.setError(e);
return ResponseEntity.badRequest().body(responseResource);
}
}
@RequestMapping(value = "{jobExecutionId}", method = RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
public JobExecutionResource getJob(@PathVariable("jobExecutionId") Long jobExecutionId) {
JobExecutionResource responseResource = new JobExecutionResource();
responseResource.setJobExecutionId(jobExecutionId);
// (4)
JobExecution jobExecution = jobExplorer.getJobExecution(jobExecutionId);
if (jobExecution == null) {
responseResource.setErrorMessage("Job execution not found.");
} else {
mappingExecutionInfo(jobExecution, responseResource);
}
return responseResource;
}
private void mappingExecutionInfo(JobExecution src, JobExecutionResource dest) {
dest.setJobName(src.getJobInstance().getJobName());
for (StepExecution se : src.getStepExecutions()) {
StepExecutionResource ser = new StepExecutionResource();
ser.setStepExecutionId(se.getId());
ser.setStepName(se.getStepName());
ser.setStatus(se.getStatus().toString());
for (Throwable th : se.getFailureExceptions()) {
ser.getFailureExceptions().add(th.toString());
}
dest.getStepExecutions().add(ser);
}
dest.setStatus(src.getStatus().toString());
dest.setExitStatus(src.getExitStatus().toString());
}
}
Sr. No. | Description |
---|---|
(1) |
Specify |
(2) |
Describe field injections of |
(3) |
Use |
(4) |
Use |
Integration of Web/batch application module setting
Batch application module (asyncbatch
) operates as a stand-alone application.
Hence, batch application module (asyncbatch
) consists of settings which are in conflict and overlapping with settings of Web application module (asyncapp-web
).
These settings must be integrated as required.
-
Integration of log configuration file
logback.xml
When multiple Logback definition files are defined in Web/batch, they do not work appropriately.+ The contents ofasyncbatch/src/main/resources/logback.xml
are integrated into same file ofasyncapp-env/src/main/resources/
and then the file is deleted. -
Data source and MyBatis configuration file are not integrated
Definitions of data source and MyBatis configuration file are not integrated between Web/batch since the definition of application context is independent due to following relation.-
asyncbatch
module of the batch is defined in the servlet as a closed context. -
asyncapp-domain
andasyncapp-env
modules of Web are defined as contexts used by entire application.
-
Cross-reference of data source and MyBatis settings by Web and batch modules
Since the scope of context for Web and batch modules is different,
data source, MyBatis settings and Mapper interface cannot be referred especially from Web module. |
CSRF countermeasures specific to REST controller
When a request is sent for REST controller in the initialization settings of Web blank project, it results in a CSRF error and execution of job is rejected. Hence, explanation is given here assuming that CSRF countermeasures are disabled by the following method. Web application created here is not published on the internet and CSRF countermeasures are disabled on the premise that REST request is not sent from a third party who can exploit CSRF as a means of attack. Please note that necessity may differ in the actual Web application depending on the operating environment. |
Build
Build Maven command and create a war file.
$ cd asyncapp
$ ls
asyncbatch/ asyncapp-web/ pom.xml
$ mvn clean package
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] TERASOLUNA Server Framework for Java (5.x) Web Blank Multi Project (MyBatis3)
[INFO] TERASOLUNA Batch Framework for Java (5.x) Blank Project
[INFO] asyncapp-web
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building TERASOLUNA Server Framework for Java (5.x) Web Blank Multi Project (MyBatis3) 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
(omitted)
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] TERASOLUNA Server Framework for Java (5.x) Web Blank Multi Project (MyBatis3) SUCCESS [ 0.226 s]
[INFO] TERASOLUNA Batch Framework for Java (5.x) Blank Project SUCCESS [ 6.481s]
[INFO] asyncapp-web ....................................... SUCCESS [ 5.400 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 12.597 s
[INFO] Finished at: 2017-02-10T22:32:43+09:00
[INFO] Final Memory: 38M/250M
[INFO] ------------------------------------------------------------------------
$
Job start and confirmation of execution results using REST Client
Here, curl command is used as a REST client and an asynchronous job is started.
$ curl -v \
-H "Accept: application/json" -H "Content-type: application/json" \
-d '{"jobParams": "param1=value1"}' \
http://localhost:8080/asyncapp-web/api/v1/job/job01
* timeout on name lookup is not supported
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8088 (#0)
> POST /asyncapp-web/api/v1/job/job01 HTTP/1.1
> Host: localhost:8088
> User-Agent: curl/7.51.0
> Accept: application/json
> Content-type: application/json
> Content-Length: 30
>
* upload completely sent off: 30 out of 30 bytes
< HTTP/1.1 200
< X-Track: 0267db93977b4552880a4704cf3e4565
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Fri, 10 Feb 2017 13:55:46 GMT
<
{"jobName":"job01","jobParams":null,"jobExecutionId":3,"error":null,"errorMessag
e":null}* Curl_http_done: called premature == 0
* Connection #0 to host localhost left intact
$
From the above, it can be confirmed that job is executed with a job execution ID jobExecutionId = 3
.
Subsequently, job execution results are fetched by using job execution ID.
$ curl -v http://localhost:8080/asyncapp-web/api/v1/job/3
* timeout on name lookup is not supported
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8088 (#0)
> GET /asyncapp-web/api/v1/job/3 HTTP/1.1
> Host: localhost:8088
> User-Agent: curl/7.51.0
> Accept: */*
>
< HTTP/1.1 200
< X-Track: 7d94bf4d383745efb20cbf37cb6a8e13
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Fri, 10 Feb 2017 14:07:44 GMT
<
{"jobExecutionId":3,"jobName":"job01","stepExecutions":[{"stepExecutionId":5,"st
epName":"job01.step01","status":"COMPLETED","failureExceptions":[]}],"status":"C
OMPLETED","exitStatus":"exitCode=COMPLETED;exitDescription=","errorMessage":null
}* Curl_http_done: called premature == 0
* Connection #0 to host localhost left intact
$
Since exitCode=COMPLETED
, it can be confirmed that the job is completed successfully.
When execution results of curl are to be determined by a shell script etc
In the example above, it is displayed upto the response message using REST API.
When only HTTP status is to be confirmed by curl command, HTTP status can be displayed in standard output by considering |
How to extend
Stopping and restarting jobs
It is necessary to stop and restart asynchronous jobs from the multiple jobs that are being executed.
Further, when jobs of identical names are running in parallel, it is necessary to target only those jobs with the issues.
Hence, job execution to be targeted must be identified and the status of the job must be confirmed.
When this premise is met, an implementation for stopping and restarting asynchronous executions is explained here.
Further, a method to add job stopping (stop) and restarting (restart) is explained
for JobController
of Implementation of controller.
Job stopping and restarting can also be implemented without using JobOperator .For details, refer Job management and identify a method suitable for this objective. |
// asyncapp/asyncapp-web/src/main/java/org/terasoluna/batch/sample/app/api/JobController.java
package org.terasoluna.batch.sample.app.api;
// omitted
@RequestMapping("job")
@RestController
public class JobController {
// omitted.
@RequestMapping(value = "stop/{jobExecutionId}", method = RequestMethod.PUT)
@Deprecated
public ResponseEntity<JobOperationResource> stop(
@PathVariable("jobExecutionId") Long jobExecutionId) {
JobOperationResource responseResource = new JobOperationResource();
responseResource.setJobExecutionId(jobExecutionId);
boolean result = false;
try {
// (1)
result = jobOperator.stop(jobExecutionId);
if (!result) {
responseResource.setErrorMessage("stop failed.");
return ResponseEntity.badRequest().body(responseResource);
}
return ResponseEntity.ok().body(responseResource);
} catch (NoSuchJobExecutionException | JobExecutionNotRunningException e) {
responseResource.setError(e);
return ResponseEntity.badRequest().body(responseResource);
}
}
@RequestMapping(value = "restart/{jobExecutionId}",
method = RequestMethod.PUT)
@Deprecated
public ResponseEntity<JobOperationResource> restart(
@PathVariable("jobExecutionId") Long jobExecutionId) {
JobOperationResource responseResource = new JobOperationResource();
responseResource.setJobExecutionId(jobExecutionId);
try {
// (2)
Long id = jobOperator.restart(jobExecutionId);
responseResource.setJobExecutionId(id);
return ResponseEntity.ok().body(responseResource);
} catch (JobInstanceAlreadyCompleteException |
NoSuchJobExecutionException | NoSuchJobException |
JobRestartException | JobParametersInvalidException e) {
responseResource.setErrorMessage(e.getMessage());
return ResponseEntity.badRequest().body(responseResource);
}
}
// omitted.
}
Sr. No. | Description |
---|---|
(1) |
Specify "stop" for job being executed by calling |
(2) |
Re-execute from the step where the job has terminated abnormally or stopped by calling |
Multiple running
Multiple running signify that a Web container is started for multiple times and waits for respective job requests.
Execution of asynchronous jobs is controlled by external RDBMS so as to connect to each application. By sharing an external RDBMS, it is possible to wait for an asynchronous job to be started across the same enclosure or another enclosure.
Applications include load balancing and redundancy for specific jobs. However, as described in Implementation of Web application, these effects cannot be obtained easily just by starting multiple Web containers or enhancing parallel operations. Sometimes measures similar to a general Web application need to be taken in order to obtain the effect. An example is given below.
-
1 request processing operates in a stateless manner according to the characteristics of Web application, however, asynchronous execution of batch is likely to have a reduced failure tolerance unless it is designed in combination with job start results and confirmation.
For example, even when Web container for starting a job is made redundant, it is difficult to confirm the progress and results of the job when the job execution ID is lost after starting a job due to failure on the client side. -
A function to distribute request destinations on the client side must be implemented and a load balancer must be introduced in order to distribute the load on multiple Web containers.
In this way, adequacy of multiple starts cannot be necessarily determined. Hence, using load balancer and reviewing a control method to send requests by Web client should be considered based on the purpose and use. A design which does not degrade the performance and fault tolerance of the asynchronous execution application is required.