Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 10

Asynchronous JAX-RS

1. Purpose of Asynchronous JAX-RS


2. Server Asynchronous Response Processing (or) Developing Asynchronous JAX-RS
Resource
2.1 Use Case Related to need of Asynchronous JAX-RS API
2.2 Configuring Vendor Specific Runtime to work with Async REST Resource
|-Configuring Async RESTEasy Runtime
|-Configuring Async JERSEY Runtime
2.3 Developing Asynchronous Resources using JAX-RS API (or) AsyncResponse API
|-Developing the Async JAX-RS Resource
|-Final Req flow
|-Exception Handling
|-Cancel
|-Status Methods
|-Timeouts
|-Callbacks
|-Use Cases for AsyncResponse
3. Asynchronous JAX-RS Client (or) AsyncInvoker Client API
3.1 Purpose of Async JAX-RS Client
3.2 Different ways of Asynchronous client Invocations
|-Using Futures
|-A different rare architectures (Specific to some use cases only)
|-Exception handling
|-Using Callbacks
3.3 Futures Versus Callbacks
|-Wrapping Up

2.3 Developing Asynchronous Resources using JAX-RS API (or)


AsyncResponse API:
Developing the Async JAX-RS Resource:
@Path("/bse")
class StockResource {
@GET
@Produces("application/xml")
public StockDetails findStock(@PathParam("stock") String stockName) {

}
}

Generally the StockResource will takes more time to process the req hence we need
to develop the Resource as Async Resource. In Async prograaming the response will
be notified to Servlet Container by the Servlet using the Handler in case of Async
Servlets similarly in RESTful to develop the Async Resources the JAX-RS API has
provided one interface called as "AsyncResponse" so now we need take this as
method param and we need to to give the response to the AsyncResponse so that it
will notifies to the JAX-RS runtime so that JAX-RS runtime will assign one thread to
take response and gives back to the JAX-RS Runtime now runtime will gives to the
Servlet Conntainer that means we are not directly returing the response. If we are
direclty returning the response the response thread must for the response so that it
cannot be used by other resources that is the reason we need to return through the
handler so that once respose collected it invokes the Runtime then runtime will
takes response and gives to the ServletContainer so now it starts one response
thread from the Response Pool to collect and handovers the response then this
thread takes the response and gives to the ServletContainer now ServletContainer
dispatches the response.

So as we are giving the response to the AsyncReponse which will acts like handler so
we need no need to take return type for our Resource method hence return type is
void.

To use server-side async response processing, we need to interact with the


AsyncResponse interface

package javax.ws.rs.container;
interface AsyncResponse {
boolean resume(Object response);
boolean resume(Throwable response);
...
}

@Path("/bse")
class StockResource {
@GET
@Produces("application/xml")
public void findStock(@PathParam("stock") String stockName,
@Suspended AsyncResponse asyncResponse) {

}
}
Here we taken AsyncReponse as param so directly we will not get access bcz
AsyncRespose impl class obj will not be created by us so inorder to get access to an
AsyncResponse instance/obj by injecting it into a JAX-RS method we need to
annotate with @Suspended annotation.
When we inject an instance of AsyncResponse using the @Suspended annotation,
the HTTP request becomes suspended from the current thread of execution.
So when annotate @Suspend JAX-RS runtime will instantiates the AsyncRespose
impl class obj and injects into our resource method so now we will get access to the
AsyncRespose. The meaning of @Suspend is the response will not give directly to
the client with which the req came rather that req will be suspended and response
will be given back through this interface that is the reason we are annotated with
@Suspended annotation.
StockResource has been turned into an asynchronous operation, when we inject an
instance of AsyncResponse using the @Suspended annotation, the HTTP request
becomes suspended from the current thread of execution. In this particular
example, the StockResource class findStock() method will never send back a
response to the client directly.

Eventhough the req thread has suspended then execution will happen bcz of
internally findStock() method spawns a new thread to handle order submission or to
process to get requested order details. This background thread processes the Order
to obtain an Stock details. It then sends a response back to the client by calling the
AsyncResponse.resume() method, passing in the instance. Invoking resume() in this
manner means that it is a successful response. So, a status code of 200 is sent back
to the client. Also, because we're passing a Java object, the resume() method will
marshal this object and send it within the HTTP response body.

@Path("/bse")
public class OrderResource {
@GET
@Produces("application/xml")
public void submit(@PathParam("stock") String stockName,
final @Suspended AsyncResponse asyncResponse) {
new Thread() {
public void run() {
Response reponse=null;
// Query the stock details from DB and bind it to StockDetails
and build the response obj response obj and gives
it to the resume() method

asyncResponse.resume(response);
}
}.start();
}
}

The media type used is determined by the @Produces annotation placed on the
original JAX-RS method. If the @Produces annotation has more than one value, then
the request’s Accept header is examined to pick the returned media type. Basically,
this is the same algorithm a regular JAX-RS method uses to determine the media
type.

Let us consider one more example


@Path("/orders")
class OrderResource {
@POST
@Consumes("application/json")
@Produces("application/json")
public void submit(final Order order,
final @Suspended AsyncResponse response) {
new Thread() {
public void run() {
OrderConfirmation confirmation = orderProcessor.process(order);
response.resume(order);
}
}.start();
}
}
Alternatively, we can pass resume() a Response object to send the client a more
specific response

@Path("/bse")
public class StockResource {
@GET
public void submit(final Order order,
@Suspended AsyncResponse asyncResponse) {
new Thread() {
public void run() {
Response response = Response.ok(confirmation,
MediaType.APPLICATION_XML_TYPE).build();
asyncResponse.resume(response);
}
}.start();
}
}

Let us take one more example

@Path("/orders")
class OrderResource {
@POST
@Consumes("application/json")
public void submit(final Order order,
final @Suspended AsyncResponse response) {
new Thread() {
public void run() {
OrderConfirmation confirmation = orderProcessor.process(order);
Response response = Response.ok(confirmation,
MediaType.APPLICATION_XML_TYPE)
.build();
response.resume(response);
}
}.start();
}
}

In the above example we’ve manually created a Response. We set the entity to the
OrderConfirmation and the content type to XML.
The resume method that is there with in the AsyncResponse will notifies to the JAX-
RS runtime response is ready come and take the response so now the JAX-RS
Runtime will takes this and gives to the ServletContainer then container will assign
one Response pool thread to collect then this response pool thread will collects and
gives to the ServletContainer it will forwards to the client.
Final Req flow:
Req cames from Client-Servlet-Container/WebContainer-web.xml-identifies it is
Async-Invokes-Forwards to JAX-RS Runtime by assigning one thread from the
Request Pool then Runtime calls Resource class method within the service()-then req
thread will suspends-while calling Resource method Req-Pool thread injects the data
to the method param it instantiate the AsyncResponse obj then suspends-so control
comes resource method- now Resource method will spawns a new thread to get
stock-calls asyncResponse.resume() method within run()-control goes to
AsyncResponse Impl class resume() method will notifies to the Runtime response is
ready-Runtime will collects- and then it notifies to the ServletContainer-Container
will assigns one Response pool thread to collect-Response thread will collects and
gives to the ServletContainer-thread will terminates-then Container will dispatches
the response to the Client.

Bcz of this we will get Server Scales-up in processing more req's and we will get de-
coupling between the components so that no one waits for someone to complete.
Note:
1. In Async Resource development we need to write swan one thread with in the
Async Resource method, If we didn't mention AsyncResponse as param then it will
be a normal Resource method.
2. Even we can take one more use case which is we already discussed LocalCourier
Vendor and DTDCCourier vendor where DTDC Courier vendor will takes more .
[All these are we need to cover by own]
Exception Handling:
Status Methods:
Timeouts:
Callbacks:
Use Cases for AsyncResponse:

You might also like