Advertisement
Guest User

Untitled

a guest
May 24th, 2017
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5 5.37 KB | None | 0 0
  1. import org.apache.log4j.Logger;
  2. import org.hibernate.exception.ExceptionUtils;
  3. import org.apache.commons.lang.ObjectUtils;
  4.  
  5. import net.sf.ehcache.CacheException;
  6. import net.sf.ehcache.CacheManager;
  7. import net.sf.ehcache.Element;
  8. import net.sf.ehcache.constructs.blocking.SelfPopulatingCache;
  9. import net.sf.ehcache.Ehcache;
  10. import net.sf.ehcache.constructs.blocking.CacheEntryFactory;
  11. import net.sf.ehcache.event.CacheEventListener;
  12.  
  13. /**
  14.  * SelfPopulatingAgedCache is a SelfPopulatingCache
  15.  * which means it uses a CacheEntryFactory to create missing elements
  16.  * and return them from get.  It also inherits the ability to block
  17.  * other attempts to get the same key while a load is in progress with
  18.  * an upper bound timeout (which does not apply to the client that first
  19.  * tries to load the key).  If you want to keep the cache fresh with
  20.  * a background thread and have the same upper bound for all calls,
  21.  * look into also using an ehcache Loader with this.
  22.  *  
  23.  * This class adds a add way to set it's timeout in the constructor,
  24.  * and also tests for expired elements and reloads them transparently.
  25.  *
  26.  * ehcache.xml can only setup the basic cache properties (age till timeout
  27.  * and so forth), so to use this decorated cache, install it like this:
  28.  *
  29.  * MyImplConstructor or similar init() method {
  30.  *  Ehcache c = CacheManager.getInstance().getEhcache("com.whatever.ThingCache");
  31.  *  if (!(c instanceof SelfPopulatingAgedCache)) {
  32.  *      c = new SelfPopulatingAgedCache(c, categoryGetter, 5000);
  33.  *  }
  34.  *  
  35.  *  All this make final usage a one-liner:
  36.  *  
  37.  *  Thing getThing(Object key) {
  38.  *    return (Thing) CacheManager.getInstance().getEhcache("com.netjets.ThingCache")
  39.  *      .get(key).getValue();
  40.  *
  41.  * @author pinkham
  42.  */
  43.  
  44. public class SelfPopulatingAgedCache extends SelfPopulatingCache {
  45.    
  46.     static final Logger logger = Logger.getLogger(SelfPopulatingAgedCache.class);
  47.    
  48.     public SelfPopulatingAgedCache(Ehcache c, CacheEntryFactory ef, int timeout) {
  49.         // super sets factory to this wrapper
  50.         super(c, new ExceptionEatingCacheEntryFactoryWrapper(ef, "Credential token expired"));
  51.         setTimeoutMillis(timeout);
  52.         CacheManager.getInstance().replaceCacheWithDecoratedCache(c, this);
  53.         // cache factory wrapper is also a listener but we need to register it
  54.         getCacheEventNotificationService().registerListener((CacheEventListener)factory);
  55.     }
  56.    
  57.     @Override
  58.     public Element get(Object key) {
  59.         try {
  60.             return super.get(key);  // decorated base cache handles expiration
  61.         } catch (CacheException e) {
  62.             // for some reason, CacheException doesn't call super(msg, cause) but has it's own cause field.
  63.             // Add the cache name too
  64.             // finally, subclass RuntimeException with empty {}
  65.             // to get the more descriptive exception name
  66.             // SelfPopulatingAgedCache$RuntimeException.
  67.             RuntimeException e2 = new RuntimeException(
  68.                     e.getMessage()+ " for cache: "+cache.getName(), e.getInitialCause()){};
  69.             //e2.setStackTrace(e.getStackTrace());   // as if they had done it right
  70.             throw e2;
  71.         }
  72.     }
  73.    
  74.     // TODO: Fix the real root cause, but meanwhile, this might buy us some time QC 44371
  75.     protected static final class ExceptionEatingCacheEntryFactoryWrapper implements CacheEventListener, CacheEntryFactory {
  76.         private CacheEntryFactory factory;
  77.         private String contains;
  78.         protected ExceptionEatingCacheEntryFactoryWrapper(CacheEntryFactory factory, String contains) {
  79.             this.factory = factory;
  80.             this.contains = contains;
  81.         }
  82.        
  83.         private Element lastExpiredElement;
  84.         public Object createEntry(Object key) throws Exception {
  85.             try {
  86.                 return factory.createEntry(key);
  87.             } catch (Exception e) {
  88.                 if (contains == null || ExceptionUtils.getStackTrace(e).contains(contains)) {
  89.                     // lets not fail if key is null
  90.                     if (lastExpiredElement != null && ObjectUtils.equals(lastExpiredElement.getObjectKey(), key)) {
  91.                         Object ret = lastExpiredElement.getObjectValue();   // keep re-using it's data
  92.                         logger.warn(factory.getClass().getName()+
  93.                                 " Ignoring exception and using old cache value: ",e);
  94.                         return ret;
  95.                     }
  96.                     logger.warn(factory.getClass().getName()+
  97.                             " Unable to ignore first exception since cache has no old value: "+e);
  98.                 }
  99.                 throw e;
  100.             } finally {
  101.                 lastExpiredElement = null;  // don't leak memory if there's no exception
  102.     }
  103.         }
  104.  
  105.         public void dispose() {}
  106.         public void notifyElementEvicted(Ehcache ehcache, Element element) {}
  107.         public void notifyElementExpired(Ehcache ehcache, Element element) {
  108.             lastExpiredElement = element;  // save it before it goes away
  109.         }
  110.         public void notifyElementPut(Ehcache ehcache, Element element) {}
  111.         public void notifyElementRemoved(Ehcache ehcache, Element element) {}
  112.         public void notifyElementUpdated(Ehcache ehcache, Element element) {}
  113.         public void notifyRemoveAll(Ehcache ehcache) {}
  114.         public Object clone() throws CloneNotSupportedException { return super.clone(); }
  115.     }  
  116. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement