I am looking to replace ehcache with infinispan because we would like to use a distributed cache to scale out.
Currently we use Ehcache as a read through cache with its BlockingCache decorator. This updates the cache form a slow web service which we cant overload.
The BlockingCache feature from Ehcache prevents the back end web service from being overloaded by stopping multiple concurrent requests of the same key being refreshed - so it only allows only one thread to do the refresh of that key, while other threads asking for the same key block/sleep until the first thread is done and so they can use its result. This provided optimal throughput and scalability for the back end as its not being overloaded with too many of the same refresh calls. Also good for the server with the cache as they are doing less external calls.
See JavaDoc: http://ehcache.org/apidocs/net/sf/ehcache/constructs/blocking/BlockingCache.html or the much better explanation why you want this: http://ehcache.org/documentation/apis/constructs
This BlockingCache decorator does not seem to be available in infinispan. I really looked and cant find it in the documentation. I looked at interceptors, cache loaders, cache decorator and per invocation flags which looked promising but no talk of a solution. Searching the forums on BlockingCache and i dont find talk of it. From looking at the open source code of BlockingCache its design is very much for local in memory cache using a local lock and so its not suitable for distributed caches or easy porting to infinispan.
Can someone please tell me what is the best approach or a drop in solution to acchieve this with inifispan distributed cache. Should we use distributed locks to block access to the key/value as its being updated - is that scalable and people do that ?
Is there a feature in infinispan that i over looked that does this ? maybe someone has an open source extension or built a solution to this already. This seems such a common thing to do. Maybe the name is not called BlockingCache but achieves the same thing. Or maybe its in the Infinispan future features list.
From what i can see we may be able to solve this either:
1) Use distributed transaction locking.
2) Have a value object wrapper which has a state flag and reference to the real value object to show state that its either: ready, expired or loading. Threads that come in get the value object holder and see the state, and so know what to do. Then only one thread does the refresh and the others block while waiting for the first thread to complete loading instead of making the cache refresh call themselves. If there is no key/value since its new then a new value object holder is put into the cache with state loading, then put to ready when its completed and set with the cache value object. Expired objects are refreshed using similar blocking approach.
3) Use an infinispan interceptor or decorator and somehow extend them.
Really would like this to be generic and work with JSR 107 JCache api. I didn’t see this feature in the JSR docs but only the read through and write through cache decorators.