Search This Blog

Monday 9 May 2016

Servlet 3.x - Async Servlets

In our last post, I touched on AsyncServlet and used it to implement a Comet Application. I decided to go into the feature into a bit more depth.
We can add listeners to our AsyncContext. Considered the previous example. I decided to attach a Listener to my AsyncContext:
    AsyncContext asyncContext = req.startAsync();
    asyncContext.setTimeout(30*1000); // 30 seconds
    asyncContext.addListener(new AsyncListener() {

      @Override
      public void onTimeout(AsyncEvent asyncEvent) throws IOException {
        System.out
            .println("The request   " + req.getAttribute("Value") + " has timedout ");
      }

      @Override
      public void onStartAsync(AsyncEvent asyncEvent) throws IOException {
        System.out.println("startAsync method  for request " + req.getAttribute("Value")
            + " has been called");

      }

      @Override
      public void onError(AsyncEvent asyncEvent) throws IOException {
        System.out.println("error  in processing request " + req.getAttribute("Value")
            + " has occured !!");

      }

      @Override
      public void onComplete(AsyncEvent arg0) throws IOException {
        System.out
            .println("The request  " + req.getAttribute("Value") + " has completed ");
      }
    });
I never saw my onStartAsync method being called - possibly becauce the Listener was attached after starting the Async mode. I didnt find any way to attach it earlier.
The onComplete method was called when complete() method was executed. If timeout was exceeded than the onTimeout method was called - That would be a good place to get rid of the Async instance - eg remove it from any processing queues and also write back a timeout error to the client
Similarly the onError method could be used to write back errors. However there is no access to the exception object here. So thats kind of a bummer.

So when do we use this feature ?
Now that we have seen the powers of Async behavior, do we switch writing all our servlets from ones that receive requests, process it and move on to ones that do this in an asynchronous manner. I think Synchronous Servlets are useful for most of our cases.
Important point to bear in mind is that Async Servlets are invisible to clients. It only affects the way a Servlet Container processes the requests. The async behavior will free up the Servlet thread to process other requests, while making some other thread responsible for completing this flow.
 Consider the login flow. Sure we could claim that there is a database operation and so we should suspend the user request, run the login operation on a separate thread. Based on the outcome generate a event which can then be used to make the servlet request alive and complete it.
Or we could do it as we do today : receive request -> process it -> write response.
Suspending the login flow is not helping as that is something that the client must receive. This is unlike an email reminder which can happen on the side for the client.
Async functionality seems a better fit for maybe auction bid updates, new email notifications etc.
The login flow is not exactly a case for push notification. It is better to complete the processing on our current thread, instead of freeing Servlet Thread x and delegating the computation to Worker Thread y - no advantage gained - since Client wants it immediately.

HTML 5 introduced two powerful concepts to aid in reverse AJAX - Server-Sent Events and WebSockets. I plan to look into them soon.

2 comments:

  1. You have done a great job. I really get wondered by reading your blog post. This was still amazing. I gained more knowledge by reading your post. Thanks for your post.
    ROI Services in Chennai

    ReplyDelete
  2. This comment has been removed by a blog administrator.

    ReplyDelete