blog.onlysimpler.com

A blog... only simpler.

Slowing Down AJAX With AOP - 30 August 2007

A web application I'm working on at the moment uses quite a lot of AJAX to make it more interactive and to add a little eye candy to the UI. A common feature of the application is to show a progress indicator when a page is waiting for a response from the server. It's a small rotating graphic that provides some visual feedback to the user so they know something is happening. A good example of this is Gmail's red "Loading..." message.

Gmail's loading message

But one problem I kept running into during development was the fact that the server was responding too quickly. Because I was running the server locally on my development machine, the browser was receiving a response from the server almost immediately. There was barely any lag.

While this is usually a good thing, in my case it was proving to be a major pain. Before the page had time to show the progress indicator the server had already returned a response. This made it very difficult for me to test if the AJAX code for the progress indicator was working correctly. Also, I was unable to see the application as it would appear in the real world - with some lag.

My first reaction was to modify the server code to include something like this:

// take a nap for 1.5 seconds
try {
    Thread.sleep(1500);
catch (InterruptedException e) {
    // ignore any exceptions
}

But I soon got sick of adding that to every method I was trying to test. And worse than that, I kept committing this "temporary" code to version control by mistake! I needed a way to slow things down without having to constantly modify code.

Aspect orient programming was the answer. I've become a big fan of AOP over the last year or so. It's really come into the mainstream recently, mainly due to it's extensive usage in Spring and to a lesser extent EJB 3.

My project uses Spring which has some pretty comprehensive AOP support right out of the box so it didn't take long to knock together a solution to my problem.

First of all I created an advice that would sleep for a configurable period of time.

import org.aspectj.lang.ProceedingJoinPoint;

public class DelayAdvice {

    private long delayPeriod;

    public DelayAdvice() {
    }

    public void setDelayPeriod(long delayPeriod) {
        this.delayPeriod = delayPeriod;
    }

    public Object delay(ProceedingJoinPoint pjp) throws Throwable {
        try {
            Thread.sleep(delayPeriod);
        } catch (InterruptedException e) {
            // ignore
        }
        return pjp.proceed();
    }
}

Then it was simply a matter of configuring Spring with a pointcut on the services I wanted to slow down.

<aop:config>
    <aop:pointcut id="serviceLayerPointcut" expression="execution(public * com.onlysimpler.SomeService.*(..))"/>
    <aop:aspect ref="delayAdvice">
        <aop:around pointcut-ref="serviceLayerPointcut" method="delay"/>
    </aop:aspect>
</aop:config>

<bean id="delayAdvice" class="com.onlysimpler.DelayAdvice">
    <property name="delayPeriod" value="2000"/>
</bean>

Simple but effective.

link