IDEMPIERE-5046 Implement background reset of expire cache (#987)
This commit is contained in:
parent
c5c334d5e9
commit
2c5efb3031
|
@ -584,24 +584,26 @@ public final class Adempiere
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void createThreadPool() {
|
private static synchronized void createThreadPool() {
|
||||||
int max = Runtime.getRuntime().availableProcessors() * 20;
|
if (threadPoolExecutor == null) {
|
||||||
int defaultMax = max;
|
int max = Runtime.getRuntime().availableProcessors() * 20;
|
||||||
Properties properties = Ini.getProperties();
|
int defaultMax = max;
|
||||||
String maxSize = properties.getProperty("MaxThreadPoolSize");
|
Properties properties = Ini.getProperties();
|
||||||
if (maxSize != null) {
|
String maxSize = properties.getProperty("MaxThreadPoolSize");
|
||||||
try {
|
if (maxSize != null) {
|
||||||
max = Integer.parseInt(maxSize);
|
try {
|
||||||
} catch (Exception e) {}
|
max = Integer.parseInt(maxSize);
|
||||||
}
|
} catch (Exception e) {}
|
||||||
if (max <= 0) {
|
}
|
||||||
max = defaultMax;
|
if (max <= 0) {
|
||||||
}
|
max = defaultMax;
|
||||||
|
}
|
||||||
|
|
||||||
// start thread pool
|
// start thread pool
|
||||||
threadPoolExecutor = new ScheduledThreadPoolExecutor(max);
|
threadPoolExecutor = new ScheduledThreadPoolExecutor(max);
|
||||||
|
|
||||||
Trx.startTrxMonitor();
|
Trx.startTrxMonitor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -690,11 +692,18 @@ public final class Adempiere
|
||||||
public static synchronized void stop() {
|
public static synchronized void stop() {
|
||||||
if (threadPoolExecutor != null) {
|
if (threadPoolExecutor != null) {
|
||||||
threadPoolExecutor.shutdown();
|
threadPoolExecutor.shutdown();
|
||||||
|
threadPoolExecutor = null;
|
||||||
}
|
}
|
||||||
log = null;
|
log = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ScheduledThreadPoolExecutor getThreadPoolExecutor() {
|
/**
|
||||||
|
*
|
||||||
|
* @return {@link ScheduledThreadPoolExecutor}
|
||||||
|
*/
|
||||||
|
public static synchronized ScheduledThreadPoolExecutor getThreadPoolExecutor() {
|
||||||
|
if (threadPoolExecutor == null)
|
||||||
|
createThreadPool();
|
||||||
return threadPoolExecutor;
|
return threadPoolExecutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -454,19 +454,43 @@ public class CCache<K,V> implements CacheInterface, Map<K, V>, Serializable
|
||||||
public void newRecord(int record_ID) {
|
public void newRecord(int record_ID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return max size of cache
|
||||||
|
*/
|
||||||
public int getMaxSize() {
|
public int getMaxSize() {
|
||||||
return m_maxSize;
|
return m_maxSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return true if cache is distributed (using hazelcast)
|
||||||
|
*/
|
||||||
public boolean isDistributed() {
|
public boolean isDistributed() {
|
||||||
return m_distributed;
|
return m_distributed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return cache hit count
|
||||||
|
*/
|
||||||
public long getHit() {
|
public long getHit() {
|
||||||
return m_hit.get();
|
return m_hit.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return cache miss count
|
||||||
|
*/
|
||||||
public long getMiss() {
|
public long getMiss() {
|
||||||
return m_miss.get();
|
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
|
} // CCache
|
||||||
|
|
|
@ -24,9 +24,11 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import org.adempiere.base.Core;
|
import org.adempiere.base.Core;
|
||||||
|
import org.compiere.Adempiere;
|
||||||
import org.idempiere.distributed.ICacheService;
|
import org.idempiere.distributed.ICacheService;
|
||||||
import org.idempiere.distributed.IClusterMember;
|
import org.idempiere.distributed.IClusterMember;
|
||||||
import org.idempiere.distributed.IClusterService;
|
import org.idempiere.distributed.IClusterService;
|
||||||
|
@ -46,7 +48,10 @@ public class CacheMgt
|
||||||
public static synchronized CacheMgt get()
|
public static synchronized CacheMgt get()
|
||||||
{
|
{
|
||||||
if (s_cache == null)
|
if (s_cache == null)
|
||||||
|
{
|
||||||
s_cache = new CacheMgt();
|
s_cache = new CacheMgt();
|
||||||
|
startCacheMonitor();
|
||||||
|
}
|
||||||
return s_cache;
|
return s_cache;
|
||||||
} // get
|
} // get
|
||||||
|
|
||||||
|
@ -68,7 +73,9 @@ public class CacheMgt
|
||||||
private static CLogger log = CLogger.getCLogger(CacheMgt.class);
|
private static CLogger log = CLogger.getCLogger(CacheMgt.class);
|
||||||
/** Cache change listeners **/
|
/** Cache change listeners **/
|
||||||
private List<CacheChangeListener> m_listeners = new ArrayList<CacheChangeListener>();
|
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;
|
public static int MAX_SIZE = 1000;
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
|
@ -441,4 +448,35 @@ public class CacheMgt
|
||||||
return maxSize <= 0 ? false : size() > maxSize;
|
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
|
} // CCache
|
||||||
|
|
Loading…
Reference in New Issue