/** * Decorate the given Cache, if necessary. * @param cache the raw Cache object, based on the configuration of this FactoryBean * @return the (potentially decorated) cache object to be registered with the CacheManager */ protected Ehcache decorateCache(Ehcache cache) { if (this.cacheEntryFactory != null) { if (this.cacheEntryFactory instanceof UpdatingCacheEntryFactory) { return new UpdatingSelfPopulatingCache(cache, (UpdatingCacheEntryFactory) this.cacheEntryFactory); } else { return new SelfPopulatingCache(cache, this.cacheEntryFactory); } } if (this.blocking) { return new BlockingCache(cache); } return cache; }
Ehcache backingCache = getCache(); Element element = backingCache.getQuiet(key); if (element != null) { return refreshElement(element, backingCache, quiet); } else { return get(key);
final Collection keys = getKeys(); LOG.debug(getName() + ": found " + keys.size() + " keys to refresh"); Ehcache backingCache = getCache(); final Element element = backingCache.getQuiet(key); LOG.debug(getName() + ": entry with key " + key + " has been removed - skipping it"); refreshElement(element, backingCache, quiet); } catch (final Exception e) { LOG.warn(getName() + "Could not refresh element " + key, e); keyWithException = key; exception = e;
/** * Looks up an entry. creating it if not found. */ @Override public Element get(final Object key) throws LockTimeoutException { Element element = super.get(key); if (element == null) { try { // Value not cached - fetch it Object value = factory.createEntry(key); element = makeAndCheckElement(key, value); } catch (final Throwable throwable) { // Could not fetch - Ditch the entry from the cache and rethrow // release the lock you acquired element = new Element(key, null); throw new CacheException("Could not fetch object for cache entry with key \"" + key + "\".", throwable); } finally { put(element); } } return element; }
element = super.get(key); } else { Sync lock = getLockForKey(key);
/** * Replace the cache with a SelfPopulatingCache decorated one if this has not been done yet. * The cacheLoaderTimeoutMillis of the original cache will be used as the timeoutMillis of the BlockingCache. * @param ehcache the original cache * @param factory the cache entry value factory * @return a BlockingCache wrapping the original one */ protected SelfPopulatingCache replaceWithSelfPopulatingCacheIfNot(Ehcache ehcache, CacheEntryFactory factory){ if (ehcache instanceof SelfPopulatingCache){ return (SelfPopulatingCache) ehcache; } SelfPopulatingCache selfPopulatingCache = new SelfPopulatingCache(ehcache, factory); selfPopulatingCache.setTimeoutMillis((int)ehcache.getCacheConfiguration().getCacheLoaderTimeoutMillis()); cacheManager.replaceCacheWithDecoratedCache(ehcache, selfPopulatingCache); return selfPopulatingCache; }
@SuppressWarnings("unchecked") @Override public V get(K key) { V result = null; Element e = cache.get(key); if (e == null){ // cache miss logger.error("Cache miss should never happened in SelfPopulatingCache: {}", cache.getName()); }else{ // cache hit result = (V) e.getObjectValue(); triggerRefreshIfNeeded(e); } return result; }
LOG.debug(getName() + ": refreshing element with key " + key); replacementElement = makeAndCheckElement(key, value);
public void run(){ if (e.getVersion() == signature){ // triple check try{ V newValue = getDirectly((K)e.getObjectKey()); if (newValue == null){ cache.remove(e.getObjectKey()); }else{ cache.put(new Element((K)e.getObjectKey(), newValue)); } }catch(Exception ex){ logger.warn("Failed to update the value associated with specified key '{}' in cache '{}'", e.getObjectKey(), cache.getName(), ex); } } } });
/** * Refresh a single element. * * @param element the Element to refresh * @param backingCache the underlying {@link Ehcache}. * @throws Exception */ protected void refreshElement(final Element element, Ehcache backingCache) throws Exception { refreshElement(element, backingCache, true); }
@Override public String toString() { return "Cache[" + self.getName() + "]"; } }
public void put(K key, V value) { self.put(new Element(key, value)); }
public HitResult getHitResult(int res) { Element elt = mHitResultCache.get(res); return (HitResult) elt.getObjectValue(); }
/** * Create a new {@link SelfPopulatingCache} and corresponding {@link CacheEntryFactory} */ protected SelfPopulatingCacheTracker createSelfPopulatingCache(Ehcache cache, int timeout, DecoratedCacheType type, long refreshinterval) { final SelfPopulatingCache selfPopulatingCache; final ThreadLocal<MethodInvocation> invocationLocal; switch (type) { case REFRESHING_SELF_POPULATING_CACHE: { final RefreshingCacheEntryFactory cacheEntryFactory = new RefreshingCacheEntryFactory(); selfPopulatingCache = new RefreshingSelfPopulatingCache(cache, cacheEntryFactory, scheduler, executor, refreshinterval); invocationLocal = cacheEntryFactory.entryFactory; break; } case SELF_POPULATING_CACHE: { final ThreadLocalCacheEntryFactory cacheEntryFactory = new ThreadLocalCacheEntryFactory(); selfPopulatingCache = new SelfPopulatingCache(cache, cacheEntryFactory); invocationLocal = cacheEntryFactory.entryFactory; break; } default: { throw new IllegalArgumentException("DecoratedCacheType " + type + " is not a supported self-populating type"); } } selfPopulatingCache.setTimeoutMillis(timeout); return new SelfPopulatingCacheTracker(selfPopulatingCache, invocationLocal); }
/** * Looks up an entry. creating it if not found. */ @Override public Element get(final Object key) throws LockTimeoutException { Element element = super.get(key); if (element == null) { try { // Value not cached - fetch it Object value = factory.createEntry(key); element = makeAndCheckElement(key, value); } catch (final Throwable throwable) { // Could not fetch - Ditch the entry from the cache and rethrow // release the lock you acquired element = new Element(key, null); throw new CacheException("Could not fetch object for cache entry with key \"" + key + "\".", throwable); } finally { put(element); } } return element; }
LOG.debug(getName() + ": refreshing element with key " + key); replacementElement = makeAndCheckElement(key, value);
/** * Refresh a single element. * * @param element the Element to refresh * @param backingCache the underlying {@link Ehcache}. * @throws Exception */ protected void refreshElement(final Element element, Ehcache backingCache) throws Exception { refreshElement(element, backingCache, true); }
@Override public String toString() { return "Cache[" + self.getName() + "]"; } }
public void put(K key, V value) { self.put(new Element(key, value)); }