Spring 3.2 Rundown, Async Support

One of the features in the latest minor release of the Spring framework (3.2), is support for Servlet 3.0 “async” processing.

In this blog I’ll show you how Spring let’s you do wizardry things like long polling in a straightforward way!

In a normal web application, the client (browser) sends HTTP requests to the server, which processes information and delivers an HTTP response. While waiting for the response, the browser normally pauses and indicates that it is waiting for a response. To alleviate the client becoming “unresponsive”, this is nowadays overcome mostly by sending the request as an AJAX request. This solves the client’s problems to a great degree.

However, a situation where the processing on the server side takes an extended amount of time, may cause problems for the server. Each (AJAX) request
that clients make will “hang” on the application server and lock up resources (such threads), while the server is trying to process it. Thus, this is where the
async functionality in Servlet 3, and Spring 3.2 comes to the rescue.

Spring async support basically comes in two variations. Both methods work in a similar fashion, namely that when a request is received, the executing thread is immediately released. Processing is done in a separate thread, before the HTTP response is written back to the client. Thus from a client side, it’s not possible to distinguish that async functionality is being used.

I built a sample application for the purpose of showing these variations, including the “normal” HTTP request/response call, and I’ll show you here how to set this up yourself.

First of all, you’ll need a project setup. Look no further than the Spring MVC Showcase project on github! In my own demo project I used a similar, but simpler, setup that I won’t show here. What I will do is highlight a few important configurations:

  • Make sure your application server supports the Servlet 3.0 spec.
  • Set the <async-supported> flag to ‘true’ on your Spring dispatcher servlet.
  • Specify that the web application is a “3.0” web application in web.xml:
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">

 

That’s about it.

My application loads a simple HTML page with three links:

home

When the first, called ‘normal’, is clicked, an MVC controller method is hit, which basically puts the thread to sleep for 9 seconds, before returning a view name.

When the second, called ‘async with callable’, is clicked, an MVC controller method is hit, which returns a java.util.Callable. The callable implementation sleeps for 9 seconds before returning a view name. In this case the response is written after the Callable returns the view.

When the third, called ‘async with deferred’, is clicked, an MVC controller method is hit, which returns a Spring DeferredResult typed to ModelAndView. The result is also stored in a local Collection. A separate method, scheduled by Spring to run every five seconds, is run concurrently. The thread simulates an external process or thread, by sleeping for 9 seconds before calling “setResult” on the DeferredResult stored in the collection. In this case, setting the result causes the response to be written!

To understand the differences between these methods, I took screenshots of the running Tomcat threads after having clicked each of the above links:

normal

In the normal case, you can see that the Tomcat exec thread is sleeping during execution of the controller method.

async
In the async case, you can see that the Tomcat exec thread releases execution of the controller method, and a separate thread (known by Spring) performs the “processing” before returning the response.

deferred
The deferred case is almost the same as the async one. The only difference is where the processing occurs, which in this case is the Spring initiated ‘pool-1-thread-1′ executor thread. Note that this thread could have been started from anywhere, it wouldn’t have to be known to Spring.

So in conclusion, I think it’s fair to say that Spring makes this  new functionality very easy to implement. Now you can start doing ‘long polling’ and stop hogging too much resources!

If you want to try these things out, I suggest that you take a look at the three Spring blogs on the topic and use the MVC Showcase project as your starting point.

For reference, below is the controller code used to demonstrate the above:

/**
 * @author Christian Fogel
 */
@Controller
public class AsyncDemoController {

    private final Queue<DeferredResult<ModelAndView>> eventQueue = new ConcurrentLinkedQueue<>();

    @RequestMapping("/normal")
    public String normalCall() throws InterruptedException {
        Thread.sleep(9000);
        return "normal";
    }

    @RequestMapping("/async")
    public Callable<String> asyncCall(final Model model) {
        return new Callable<String>() {
            @Override
            public String call() throws Exception {
                Thread.sleep(9000);
                return "async";
            }
        };
    }

    @RequestMapping("/deferred")
    public
    @ResponseBody
    DeferredResult<ModelAndView> deferredCall() {
        DeferredResult<ModelAndView> result = new DeferredResult<>();
        this.eventQueue.add(result);
        return result;
    }

    @Scheduled(fixedRate = 5000)
    public void simulateExternalThread() throws InterruptedException {
        Thread.sleep(9000);
        for (DeferredResult<ModelAndView> result : this.eventQueue) {
            result.setResult(new ModelAndView("deferred"));
            this.eventQueue.remove(result);
        }
    }

}

 

 

Spring 3.2 Rundown, Intro

The new version of Spring, dubbed 3.2, went “GA” in December, and I’ve taken a look at the new features and what you can do with them. This will be a rundown of selected features, with comments and examples.

First off, I’d recommend you to refer to the blog post, this video briefing and the 3.2 reference, in increasing order of detail of what the 3.2 release brings. Or you can stick around here for a distilled version! I’m going to comment and provide examples of the following topics in this blog series:

Agile Life: Personal Kanban Revisited

In my previous post on personal kanban, I showed how I used a simple piece of cardboard to implement the flow at work. Having accustomed myself to the method, I tried to give it a go also at home:

Nothing done yet!

The picture above depicts my bedroom door, and you might notice (I suppose it might not be obvious) that my Kanban flow is vertical and not horizontal. It doesn’t really matter though – I just thought that the three areas separated by the wood working and the visibility of the door made for a splendid Kanban board for my purposes.

There is nothing new here, the method is the same as the one I used at work, but I’d still like to point out two things.

I’ve actually tried this exact method on a couple of weekends. You know the feeling you get when you have a couple of days off (perhaps even a few weeks of vacation), and in the back of your head is a long backlog of various things you need to get done. BUT, instead of organizing these tasks in your mind and start ticking them off, you let them slip and you go watch a game of football or some other completely unrelated thing.

Now, with this extraordinarily simple method, I usually get 80-90% of the tasks done, which is a vast improvement over a “no method” approach and oddly enough, also an improvement over writing all these tasks down on a piece of paper! In addition, some of the tasks that I couldn’t complete were impossible, or very hard (because they required to be done on a weekday for a certain retailer to be open, or similar impediments), which makes the statistics even better.

The second thing is, again, transparency. I suspect the reason why this method is better than “no method” or “paper method”, is the visibility of the tasks glaring at me from the top row of the door. Not to mention my cohabitant’s reaction to having a part of our home filled with little, yellow, beautiful(?), post-it notes :-). She even took a picture and shared it on a particular social networking site… Furthermore, she was WELL aware that I hadn’t completed certain, “important” tasks on the list and kept bugging me about them.

Hmm, I guess there are “some” drawbacks of this method after all…