Saturday, August 20, 2011


Caching Exceptions in server applications -
In web applications it’s common that  response page of certain types can be cached for given http request, similar approach could be used to cache the exceptions in the server side applications as well. If the reason for any exception known upfront that it will be applicable for given amount of time, there is a opportunity to cache these to reduce the load on resources. This could be huge gain in cases where a particular piece of code is doing heavy operations like cpu intensive tasks, making remote calls, Database/File manipulation etc..
Here is a solution making use of Java generics.
For Ex:
public static int mockHeavyOperation(String someData) throws FileNotFoundException,Exception{
        Thread.sleep(3000);//simulating some heavy operation
        if(true) throw new FileNotFoundException();
        return 10;
    }
Can be converted into
public static int mockHeavyOperationWithCacheExceptionHandler(String someData) throws FileNotFoundException{
        return new ExceptionCacheTemplate<Integer,FileNotFoundException>(){
                @Override
                public Integer handle() throws Exception {
                    Thread.sleep(3000); //simulating some heavy operation
                        if(true) throw new FileNotFoundException("Checked Exception");
                        return 10;
                    }
           }.runIn(new ExceptionCacheTemplate.ExceptionKey(someData,40000));
    }
As we can see from above code extra 4 lines are doing the trick.
If we run the first operation 10 times it takes 30000 millis where as 2nd example takes only 3000 millis, that's a huge gain I suppose.
1. The input information that resulted in exception can be stored as part of Exception Key class. It can be any class including String as shown above as long as it implements equals/hashCode(). runIn method works directly with String as well. If any Exception re-appears within the interval 40000 as shown above the Exception will be thrown from cache.
2. Only the exceptions that are included as part of the  generic exceptions,
3. A custom map can be provided to manage the expiring of cached exceptions, Default implementation will be managing through the value provided while creating cache key.
"public Map getCache()" can be overridden to provide different implementation
For example Google's Guava library provides awesome fluent interface to manage expiry of keys.
Map<Key,Graph> graphs = new MapMaker()
       .concurrencyLevel(4)
       .weakKeys()
       .maximumSize(10000)
       .expireAfterWrite(10, TimeUnit.MINUTES)
       .makeComputingMap(
           new Function() {
             public Graph apply(Key key) {
               return createExpensiveGraph(key);
             }
           });

It can be handled at the framework level making it completely transparent to the applications.
ExceptionTamplate is available in github
Bookmark and Share