Sunday, February 9, 2014

Async request processing in Java EE 7

There are multiple features in J2EE/java now to make enterprise application process the request asynchronously.

1. Async request/response in Servlet 3.0

If a servlet processing is taking lot of time then servlet container may only be able to serve limited number of clients depending on the number of threads configured for servlet container. This would negatively impact the server throughput.

This is not a optimal handling of server resources as threads may not be doing CPU activity all the time. They may be busy in io etc. CPU is not completely utilized yet we end up refusing the connections to the users. Servlet 3.0 provides the framwork/apis for processing the requests asynchronously in a separate thread other than servlet container thread. This way actual processing is done in a separate user defined thread and the response is sent back to the caller through async callback api provided by the servlet conatiner.

Please note that the client making the request can be asynchronous using the client library https://jersey.java.net/documentation/latest/async.html#d0e8674.

The following URL http://www.javacodegeeks.com/2013/08/async-servlet-feature-of-servlet-3.html has a good explanation of the apis with a sample application.

2. Async EJB 3.1


EJB 3.1 allows the EJB method to be called asynchronously if it is annoted using @Asynchronous. Such methods are called by the container in a separate thread. CLient will not be blocked for the response.There are currently two flavors which are supported:
* Fire and forget methods where result is not expected. Method has a void return type.
* Methods that have some return type. Method returns java.util.concurrent.Future object which can be polled for method execution status and retrieving the return object.

Following URL shoes some code snippets: http://satishgopal.wordpress.com/2011/04/24/ejb-3-1-asynchronous-methods/

3. Support for WebSocket

Java EE 7 supports WebSocket applications. WebSocket application can be deployed in a standard way. Java annotation @ServerEndpoint can be specified at the class level for exposinjg a class as WebSocket endpoint. Additionally @onMessage method annotation marks the method for receiving the messages.

This is a sample picked from http://docs.oracle.com/javaee/7/tutorial/doc/websocket004.htm.

@ServerEndpoint("/echo")
public class EchoEndpoint {
   @OnMessage
   public void onMessage(Session session, String msg) {
      try {
         session.getBasicRemote().sendText(msg);
      } catch (IOException e) { ... }
   }
}


Some important points to be noted:

* By default for each client connection, a separate instance of the endpoint class is created.
* Client connection is maintained till the connection is closed. During the communication, a single instance which was created initially will serve the requests.
* Client can chose to serve multiple client connections through a same instance by specifying custom ServerEndpointConfig.Configurator. In this case, application developer is responsible for handling concurrency.
* Only URL template parameters can be passes to the WebSocket endpoint. Unlike REST services there is no notion of query parameters.
* Encoders and decoders can be defined to serialize/deserialize java objects to/from the WebSocket stream.

http://docs.oracle.com/javaee/7/tutorial/doc/websocket.htm#GKJIQ5 provides a very good explanation.

4. JAX RS 2.0

The support is similar to Servlet async support. Methods can be marked as async using @Suspended as the method parameter. This annotation injects AsyncResponse as the method parameter. Any method with @Suspended AsyncResponse as the parameter is understood as asynchronous by the runtime. Method call is immediately returned while server keeps the connection open waiting for the AsyncResponse.

This is a sample picked from https://jersey.java.net/documentation/latest/async.html

@Path("/resource")
public class AsyncResource {
    @GET
    public void asyncGet(@Suspended final AsyncResponse asyncResponse) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                String result = veryExpensiveOperation();
                asyncResponse.resume(result);
            }

            private String veryExpensiveOperation() {
                // ... very expensive operation
            }
        }).start();
    }
}


https://jersey.java.net/documentation/latest/async.html has the details.