diff --git a/org.adempiere.base/src/org/compiere/Adempiere.java b/org.adempiere.base/src/org/compiere/Adempiere.java index 46b4709f34..9c860f382a 100644 --- a/org.adempiere.base/src/org/compiere/Adempiere.java +++ b/org.adempiere.base/src/org/compiere/Adempiere.java @@ -584,24 +584,26 @@ public final class Adempiere } } - private static void createThreadPool() { - int max = Runtime.getRuntime().availableProcessors() * 20; - int defaultMax = max; - Properties properties = Ini.getProperties(); - String maxSize = properties.getProperty("MaxThreadPoolSize"); - if (maxSize != null) { - try { - max = Integer.parseInt(maxSize); - } catch (Exception e) {} + private static synchronized void createThreadPool() { + if (threadPoolExecutor == null) { + int max = Runtime.getRuntime().availableProcessors() * 20; + int defaultMax = max; + Properties properties = Ini.getProperties(); + String maxSize = properties.getProperty("MaxThreadPoolSize"); + if (maxSize != null) { + try { + max = Integer.parseInt(maxSize); + } catch (Exception e) {} + } + if (max <= 0) { + max = defaultMax; + } + + // start thread pool + threadPoolExecutor = new ScheduledThreadPoolExecutor(max); + + Trx.startTrxMonitor(); } - if (max <= 0) { - max = defaultMax; - } - - // start thread pool - threadPoolExecutor = new ScheduledThreadPoolExecutor(max); - - Trx.startTrxMonitor(); } /** @@ -690,11 +692,18 @@ public final class Adempiere public static synchronized void stop() { if (threadPoolExecutor != null) { threadPoolExecutor.shutdown(); + threadPoolExecutor = null; } log = null; } - public static ScheduledThreadPoolExecutor getThreadPoolExecutor() { + /** + * + * @return {@link ScheduledThreadPoolExecutor} + */ + public static synchronized ScheduledThreadPoolExecutor getThreadPoolExecutor() { + if (threadPoolExecutor == null) + createThreadPool(); return threadPoolExecutor; } diff --git a/org.adempiere.base/src/org/compiere/util/CCache.java b/org.adempiere.base/src/org/compiere/util/CCache.java index 230b2912b7..be6832dd19 100644 --- a/org.adempiere.base/src/org/compiere/util/CCache.java +++ b/org.adempiere.base/src/org/compiere/util/CCache.java @@ -454,19 +454,43 @@ public class CCache implements CacheInterface, Map, Serializable public void newRecord(int record_ID) { } + /** + * + * @return max size of cache + */ public int getMaxSize() { return m_maxSize; } + /** + * + * @return true if cache is distributed (using hazelcast) + */ public boolean isDistributed() { return m_distributed; } + /** + * + * @return cache hit count + */ public long getHit() { return m_hit.get(); } + /** + * + * @return cache miss count + */ public long getMiss() { return m_miss.get(); } + + /** + * + * @return true if cache has expire + */ + public boolean isExpire() { + return m_expire > 0 && m_timeExp > 0 && m_timeExp < System.currentTimeMillis(); + } } // CCache diff --git a/org.adempiere.base/src/org/compiere/util/CacheMgt.java b/org.adempiere.base/src/org/compiere/util/CacheMgt.java index 9aae940947..6e8ed86e3d 100644 --- a/org.adempiere.base/src/org/compiere/util/CacheMgt.java +++ b/org.adempiere.base/src/org/compiere/util/CacheMgt.java @@ -24,9 +24,11 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; import java.util.logging.Level; import org.adempiere.base.Core; +import org.compiere.Adempiere; import org.idempiere.distributed.ICacheService; import org.idempiere.distributed.IClusterMember; import org.idempiere.distributed.IClusterService; @@ -46,7 +48,10 @@ public class CacheMgt public static synchronized CacheMgt get() { if (s_cache == null) + { s_cache = new CacheMgt(); + startCacheMonitor(); + } return s_cache; } // get @@ -68,7 +73,9 @@ public class CacheMgt private static CLogger log = CLogger.getCLogger(CacheMgt.class); /** Cache change listeners **/ private List m_listeners = new ArrayList(); - + /** Background monitor to clear expire cache */ + private static final CacheMgt.CacheMonitor s_monitor = new CacheMgt.CacheMonitor(); + /** Default maximum cache size **/ public static int MAX_SIZE = 1000; static { @@ -441,4 +448,35 @@ public class CacheMgt return maxSize <= 0 ? false : size() > maxSize; } } + + private static synchronized void startCacheMonitor() + { + Adempiere.getThreadPoolExecutor().scheduleWithFixedDelay(s_monitor, 5, 5, TimeUnit.MINUTES); + } + + private static class CacheMonitor implements Runnable + { + + public void run() + { + CacheMgt instance = CacheMgt.get(); + if (!instance.m_instances.isEmpty()) + { + CacheInterface[] caches = instance.m_instances.toArray(new CacheInterface[0]); + for(int i = 0; i < caches.length; i++) + { + if (!(caches[i] instanceof CCache)) + continue; + CCache cache = (CCache) caches[i]; + if (cache.isDistributed() || cache.getExpireMinutes() <= 0) + continue; + + if (cache.isExpire()) + { + cache.reset(); + } + } + } + } + } } // CCache