Advertisement
Guest User

Untitled

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