I’ve been writing some caching code recently at work and it occurred to me that I should really look into some caching API’s. Whilst talking to Matt at the last London-Java meetup, the discussion of caching came up. He said he’d looked at “OSCache”:http://www.opensymphony.com/oscache/, but decided against using it due to a complaint with its API. Apparently when you get an entry from the cache, if it doesn’t exist it throws an exception. Not fulling believing this to be true, I looked through the API docs (note to the OpenSymphony guys – a simple tutorial would be nice) to find that he is completely correct. This from the
NeedsRefreshException – Thrown when the object either doesn’t exist, or exists but is stale. When this exception occurs, the CacheEntry corresponding to the supplied key will be locked and other threads requesting this entry will potentially be blocked until the caller repopulates the cache. If the caller choses not to repopulate the cache, they must instead call cancelUpdate(String).
This strikes me has bizare to say the least. First off exceptions are being used to control logic flow, which is a bad thing. Exceptions are for errors in your code – be they user driven, programatic or due to system disruption (please don’t quote the whole
NumberFormatException being thrown from the various number
parse methods – thats just wrong). Secondly, the obvious (to me) way to design a cache is to allow a pluggable load strategy to the cache, and if the content doesn’t exist the cache itself goes and gets the content. Then if there is a problem loading the content you would get an error thrown, which would of course be an unchecked exception as it will be a programmatic or system environment error. Here the cache is saying “I’m stupid, fix me” and will then perhaps even lock your thread until you do. To be of any use to me I’m going to have to wrap OSCache with my own Cache class to do this for me.
I am struggling to think of a single advantage to this approach. Everywhere you want to use the
getFromCache() method you are now forced to wrap it with a try-catch block, and then have to repopulate the cache if it fails. A pluggable content-loading system wouldn’t be hard to write. I have come to the conclusion that I must be missing something. Either the javadoc is wrong or there is a very good reason for
getFromCache() to work like this. Can someone put me right?