IDEMPIERE-5046 Implement background reset of expire cache (#987)

This commit is contained in:
hengsin 2021-11-19 22:55:04 +08:00 committed by GitHub
parent c5c334d5e9
commit 2c5efb3031
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 90 additions and 19 deletions

View File

@ -584,7 +584,8 @@ public final class Adempiere
}
}
private static void createThreadPool() {
private static synchronized void createThreadPool() {
if (threadPoolExecutor == null) {
int max = Runtime.getRuntime().availableProcessors() * 20;
int defaultMax = max;
Properties properties = Ini.getProperties();
@ -603,6 +604,7 @@ public final class Adempiere
Trx.startTrxMonitor();
}
}
/**
* Startup Adempiere Environment.
@ -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;
}

View File

@ -454,19 +454,43 @@ public class CCache<K,V> implements CacheInterface, Map<K, V>, 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

View File

@ -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<CacheChangeListener> m_listeners = new ArrayList<CacheChangeListener>();
/** 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