05.Asynchronous processing - JohnyzHub/jax-rs GitHub Wiki
When the restful web service is accessed synchronously, a new thread will be assigned by the container to process that request and that thread will be alive until the application finish processing the request. This may degrade the scalability of the application if the process takes unusually long time to finish. To address this concern jax-rs has provided the feature of processing the long running requests asynchronously.
Asynchronous feature can be obtained by using one of the below two ways, on server side:
This class models an execution context (transaction, security, etc) with which the Work instance must be executed. This class is provided as a convenience for easily creating executioncontext instances by extending this class and overriding only those methods of interest. the below code shows a possible way of using this class,
@Path("directory/async")
public class MovieAsyncService {
@Context private ExecutionContextctx;
@GET
@Path("movie")
@Asynchronous
public void findMovie(@DefaultValue("1") @QueryParam("number") int number) {
Executors.newSingleThreadExecutor().submit( new Runnable() {
public void run() {
Thread.sleep(10000);
ctx.resume("Hello async world!");
} });
ctx.suspend();
return;
}
}
key points to notice:
- @Asynchronous annotation, which will work in the fire-and-forget manner.
- A new thread will be started to handle the task of processing the client's request.
- This new thread will be assigned to an executor instance, which takes the responsibility for managing and running multiple threads.
- The main thread will be released using
ctx.suspend
so it can accept the new requests. - Once the new worker thread has finished preparing the response, it notifies the jakarta ee container by calling
ctx.resume
, that the response is ready to be sent back to the client. - If the worker thread finishes preparing the response and calls
ctx.resume
before the main thread has been released, then the async process is ignored, the regular regular request processing will happen and the response will be sent back to the client immediately.
Inject a suspended AsyncResponse into a parameter of an invoked JAX-RS resource or sub-resource method. The injected AsyncResponse instance is bound to the processing of the active request and can be used to resume the request processing when a response is available.
Check the class MovieAsyncService.java to know the complete implementation details of the asynchronous service, using the suspended annotation on the server side.
Accessing the restful web service asynchronously
Check the class MovieAsyncClient.java to know the complete implementation details of consuming the asynchronous service, on the client side.