|
@@ -30,12 +30,12 @@ import password.pwm.util.localdb.LocalDB;
|
|
|
import password.pwm.util.localdb.LocalDBException;
|
|
|
import password.pwm.util.logging.PwmLogger;
|
|
|
|
|
|
-import java.io.Serializable;
|
|
|
import java.time.Instant;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
|
-import java.util.Timer;
|
|
|
import java.util.TimerTask;
|
|
|
+import java.util.concurrent.ExecutorService;
|
|
|
+import java.util.concurrent.atomic.AtomicInteger;
|
|
|
|
|
|
public class LocalDBCacheStore implements CacheStore {
|
|
|
private static final PwmLogger LOGGER = PwmLogger.forClass(LocalDBCacheStore.class);
|
|
@@ -45,13 +45,10 @@ public class LocalDBCacheStore implements CacheStore {
|
|
|
private static final int TICKS_BETWEEN_PURGE_CYCLES = 1000;
|
|
|
|
|
|
private final LocalDB localDB;
|
|
|
- private final Timer timer;
|
|
|
- private int ticks = 0;
|
|
|
+ private final ExecutorService timer;
|
|
|
+ private final AtomicInteger ticks = new AtomicInteger(0);
|
|
|
|
|
|
- private int readCount;
|
|
|
- private int storeCount;
|
|
|
- private int hitCount;
|
|
|
- private int missCount;
|
|
|
+ private final CacheStoreInfo cacheStoreInfo = new CacheStoreInfo();
|
|
|
|
|
|
LocalDBCacheStore(final PwmApplication pwmApplication) {
|
|
|
this.localDB = pwmApplication.getLocalDB();
|
|
@@ -60,23 +57,23 @@ public class LocalDBCacheStore implements CacheStore {
|
|
|
} catch (LocalDBException e) {
|
|
|
LOGGER.error("error while clearing LocalDB CACHE DB during init: " + e.getMessage());
|
|
|
}
|
|
|
- timer = new Timer(JavaHelper.makeThreadName(pwmApplication,LocalDBCacheStore.class),true);
|
|
|
+ timer = JavaHelper.makeSingleThreadExecutorService(pwmApplication, LocalDBCacheStore.class);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void store(final CacheKey cacheKey, final Instant expirationDate, final String data)
|
|
|
throws PwmUnrecoverableException
|
|
|
{
|
|
|
- ticks++;
|
|
|
- storeCount++;
|
|
|
+ ticks.incrementAndGet();
|
|
|
+ cacheStoreInfo.incrementStoreCount();
|
|
|
try {
|
|
|
- localDB.put(DB,cacheKey.getHash(),JsonUtil.serialize(new ValueWrapper(cacheKey, expirationDate, data)));
|
|
|
+ localDB.put(DB,cacheKey.getHash(),JsonUtil.serialize(new CacheValueWrapper(cacheKey, expirationDate, data)));
|
|
|
} catch (LocalDBException e) {
|
|
|
LOGGER.error("error while writing cache: " + e.getMessage());
|
|
|
}
|
|
|
- if (ticks > TICKS_BETWEEN_PURGE_CYCLES) {
|
|
|
- ticks = 0;
|
|
|
- timer.schedule(new PurgerTask(),1);
|
|
|
+ if (ticks.get() > TICKS_BETWEEN_PURGE_CYCLES) {
|
|
|
+ ticks.set(0);
|
|
|
+ timer.execute(new PurgerTask());
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -84,7 +81,7 @@ public class LocalDBCacheStore implements CacheStore {
|
|
|
public String read(final CacheKey cacheKey)
|
|
|
throws PwmUnrecoverableException
|
|
|
{
|
|
|
- readCount++;
|
|
|
+ cacheStoreInfo.incrementReadCount();
|
|
|
final String hashKey = cacheKey.getHash();
|
|
|
final String storedValue;
|
|
|
try {
|
|
@@ -95,10 +92,10 @@ public class LocalDBCacheStore implements CacheStore {
|
|
|
}
|
|
|
if (storedValue != null) {
|
|
|
try {
|
|
|
- final ValueWrapper valueWrapper = JsonUtil.deserialize(storedValue, ValueWrapper.class);
|
|
|
+ final CacheValueWrapper valueWrapper = JsonUtil.deserialize(storedValue, CacheValueWrapper.class);
|
|
|
if (cacheKey.equals(valueWrapper.getCacheKey())) {
|
|
|
if (valueWrapper.getExpirationDate().isAfter(Instant.now())) {
|
|
|
- hitCount++;
|
|
|
+ cacheStoreInfo.getHitCount();
|
|
|
return valueWrapper.getPayload();
|
|
|
}
|
|
|
}
|
|
@@ -111,57 +108,15 @@ public class LocalDBCacheStore implements CacheStore {
|
|
|
LOGGER.error("error while purging record from cache: " + e.getMessage());
|
|
|
}
|
|
|
}
|
|
|
- missCount++;
|
|
|
+ cacheStoreInfo.incrementMissCount();
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public CacheStoreInfo getCacheStoreInfo() {
|
|
|
- final CacheStoreInfo cacheStoreInfo = new CacheStoreInfo();
|
|
|
- cacheStoreInfo.setReadCount(readCount);
|
|
|
- cacheStoreInfo.setStoreCount(storeCount);
|
|
|
- cacheStoreInfo.setHitCount(hitCount);
|
|
|
- cacheStoreInfo.setMissCount(missCount);
|
|
|
- try {
|
|
|
- cacheStoreInfo.setItemCount(localDB.size(DB));
|
|
|
- } catch (LocalDBException e) {
|
|
|
- LOGGER.error("error generating cacheStoreInfo: " + e.getMessage());
|
|
|
- }
|
|
|
return cacheStoreInfo;
|
|
|
}
|
|
|
|
|
|
- private static class ValueWrapper implements Serializable {
|
|
|
- final CacheKey cacheKey;
|
|
|
- final Instant expirationDate;
|
|
|
- final String payload;
|
|
|
-
|
|
|
- private ValueWrapper(
|
|
|
- final CacheKey cacheKey,
|
|
|
- final Instant expirationDate,
|
|
|
- final String payload
|
|
|
- )
|
|
|
- {
|
|
|
- this.cacheKey = cacheKey;
|
|
|
- this.expirationDate = expirationDate;
|
|
|
- this.payload = payload;
|
|
|
- }
|
|
|
-
|
|
|
- public CacheKey getCacheKey()
|
|
|
- {
|
|
|
- return cacheKey;
|
|
|
- }
|
|
|
-
|
|
|
- public Instant getExpirationDate() {
|
|
|
- return expirationDate;
|
|
|
- }
|
|
|
-
|
|
|
- public String getPayload()
|
|
|
- {
|
|
|
- return payload;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
private boolean purgeExpiredRecords() throws LocalDBException {
|
|
|
final List<String> removalKeys = new ArrayList<>();
|
|
|
final LocalDB.LocalDBIterator<String> localDBIterator = localDB.iterator(DB);
|
|
@@ -175,8 +130,8 @@ public class LocalDBCacheStore implements CacheStore {
|
|
|
if (key != null) {
|
|
|
final String strValue = localDB.get(DB, key);
|
|
|
if (strValue != null) {
|
|
|
- final ValueWrapper valueWrapper = JsonUtil.deserialize(strValue, ValueWrapper.class);
|
|
|
- if (valueWrapper.expirationDate.isBefore(Instant.now())) {
|
|
|
+ final CacheValueWrapper valueWrapper = JsonUtil.deserialize(strValue, CacheValueWrapper.class);
|
|
|
+ if (valueWrapper.getExpirationDate().isBefore(Instant.now())) {
|
|
|
keep = true;
|
|
|
}
|
|
|
}
|
|
@@ -214,4 +169,15 @@ public class LocalDBCacheStore implements CacheStore {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int itemCount()
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ return localDB.size(DB);
|
|
|
+ } catch (LocalDBException e) {
|
|
|
+ LOGGER.error("unexpected error reading size from localDB: " + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
}
|