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.
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.