Change to explicitly 'expiring' the oldest session.
This commit is contained in:
parent
3a7507c832
commit
15e9ba30f0
|
@ -7,25 +7,31 @@ import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class MaxSizeSessionCacheDecorator implements SessionCache {
|
public class ExplicitExpirySessionCacheDecorator implements SessionCache {
|
||||||
|
|
||||||
|
|
||||||
public final int maxSize;
|
|
||||||
public final SessionCache sessionCache;
|
public final SessionCache sessionCache;
|
||||||
|
|
||||||
private final List<String> sessionIds;
|
private final List<String> sessionIds;
|
||||||
|
|
||||||
public MaxSizeSessionCacheDecorator(SessionCache sessionCache, int maxSize) {
|
public ExplicitExpirySessionCacheDecorator(SessionCache sessionCache) {
|
||||||
this.sessionCache = sessionCache;
|
this.sessionCache = sessionCache;
|
||||||
this.maxSize = maxSize;
|
|
||||||
this.sessionIds = new ArrayList<>(sessionCache.getSessionIds());
|
this.sessionIds = new ArrayList<>(sessionCache.getSessionIds());
|
||||||
if (this.sessionIds.size() > maxSize) {
|
|
||||||
throw new IllegalArgumentException("Session cache size exceeds the maximum size");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean expireOldestSession() {
|
||||||
|
if (sessionIds.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String oldestSessionId = sessionIds.get(0);
|
||||||
|
sessionIds.remove(oldestSessionId);
|
||||||
|
sessionCache.removeSession(oldestSessionId);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String cacheSession(ValidationEngine validationEngine) {
|
public String cacheSession(ValidationEngine validationEngine) {
|
||||||
checkSizeAndMaintainMax(null);
|
maintainSessionIds(null);
|
||||||
String key = sessionCache.cacheSession(validationEngine);
|
String key = sessionCache.cacheSession(validationEngine);
|
||||||
sessionIds.add(key);
|
sessionIds.add(key);
|
||||||
return key;
|
return key;
|
||||||
|
@ -33,12 +39,14 @@ public class MaxSizeSessionCacheDecorator implements SessionCache {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String cacheSession(Supplier<ValidationEngine> validationEngineSupplier) {
|
public String cacheSession(Supplier<ValidationEngine> validationEngineSupplier) {
|
||||||
checkSizeAndMaintainMax(null);
|
maintainSessionIds(null);
|
||||||
ValidationEngine validationEngine = validationEngineSupplier.get();
|
ValidationEngine validationEngine = validationEngineSupplier.get();
|
||||||
return sessionCache.cacheSession(validationEngine);
|
String key = sessionCache.cacheSession(validationEngine);
|
||||||
|
sessionIds.add(key);
|
||||||
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkSizeAndMaintainMax(String keyToAdd) {
|
private void maintainSessionIds(String keyToAdd) {
|
||||||
if (keyToAdd != null || sessionCache.sessionExists(keyToAdd)) {
|
if (keyToAdd != null || sessionCache.sessionExists(keyToAdd)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -46,16 +54,11 @@ public class MaxSizeSessionCacheDecorator implements SessionCache {
|
||||||
//Sync our tracked keys, in case the underlying cache has changed
|
//Sync our tracked keys, in case the underlying cache has changed
|
||||||
this.sessionIds.removeIf(key -> !sessionIds.contains(key));
|
this.sessionIds.removeIf(key -> !sessionIds.contains(key));
|
||||||
|
|
||||||
if (this.sessionIds.size() >= maxSize) {
|
|
||||||
final String key = this.sessionIds.remove(0);
|
|
||||||
sessionCache.removeSession(key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String cacheSession(String sessionId, ValidationEngine validationEngine) {
|
public String cacheSession(String sessionId, ValidationEngine validationEngine) {
|
||||||
checkSizeAndMaintainMax(sessionId);
|
maintainSessionIds(sessionId);
|
||||||
cacheSession(sessionId, validationEngine);
|
|
||||||
return sessionCache.cacheSession(
|
return sessionCache.cacheSession(
|
||||||
sessionId, validationEngine);
|
sessionId, validationEngine);
|
||||||
}
|
}
|
|
@ -32,23 +32,54 @@ public class MaxSizeSessionCacheDecoratorTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void trivialCase() {
|
public void trivialExpiryTest() {
|
||||||
|
|
||||||
MaxSizeSessionCacheDecorator maxSizeSessionCacheDecorator = new MaxSizeSessionCacheDecorator(new PassiveExpiringSessionCache(), 4);
|
ExplicitExpirySessionCacheDecorator sessionCache = new ExplicitExpirySessionCacheDecorator(new PassiveExpiringSessionCache());
|
||||||
|
|
||||||
LinkedHashMap<String, ValidationEngine> initialEngines = addMockedEngines(maxSizeSessionCacheDecorator, 3);
|
LinkedHashMap<String, ValidationEngine> initialEngines = addMockedEngines(sessionCache, 3);
|
||||||
|
|
||||||
Assertions.assertEquals(3, maxSizeSessionCacheDecorator.getSessionIds().size());
|
Assertions.assertEquals(3, sessionCache.getSessionIds().size());
|
||||||
|
|
||||||
LinkedHashMap<String, ValidationEngine> newEngines = addMockedEngines(maxSizeSessionCacheDecorator, 2);
|
Assertions.assertTrue(sessionCache.getSessionIds().contains(getKeyByIndex(initialEngines, 0)));
|
||||||
|
Assertions.assertTrue(sessionCache.getSessionIds().contains(getKeyByIndex(initialEngines, 1)));
|
||||||
|
Assertions.assertTrue(sessionCache.getSessionIds().contains(getKeyByIndex(initialEngines, 2)));
|
||||||
|
|
||||||
|
Assertions.assertTrue(sessionCache.expireOldestSession());
|
||||||
|
|
||||||
Assertions.assertEquals(4, maxSizeSessionCacheDecorator.getSessionIds().size());
|
Assertions.assertEquals(2, sessionCache.getSessionIds().size());
|
||||||
Assertions.assertTrue(maxSizeSessionCacheDecorator.getSessionIds().contains(getKeyByIndex(initialEngines, 1)));
|
Assertions.assertTrue(sessionCache.getSessionIds().contains(getKeyByIndex(initialEngines, 1)));
|
||||||
Assertions.assertTrue(maxSizeSessionCacheDecorator.getSessionIds().contains(getKeyByIndex(initialEngines, 2)));
|
Assertions.assertTrue(sessionCache.getSessionIds().contains(getKeyByIndex(initialEngines, 2)));
|
||||||
Assertions.assertTrue(maxSizeSessionCacheDecorator.getSessionIds().contains(getKeyByIndex(newEngines, 0)));
|
|
||||||
Assertions.assertTrue(maxSizeSessionCacheDecorator.getSessionIds().contains(getKeyByIndex(newEngines, 1)));
|
|
||||||
|
|
||||||
|
LinkedHashMap<String, ValidationEngine> newEngines = addMockedEngines(sessionCache, 2);
|
||||||
|
|
||||||
|
Assertions.assertEquals(4, sessionCache.getSessionIds().size());
|
||||||
|
Assertions.assertTrue(sessionCache.getSessionIds().contains(getKeyByIndex(initialEngines, 1)));
|
||||||
|
Assertions.assertTrue(sessionCache.getSessionIds().contains(getKeyByIndex(initialEngines, 2)));
|
||||||
|
Assertions.assertTrue(sessionCache.getSessionIds().contains(getKeyByIndex(newEngines, 0)));
|
||||||
|
Assertions.assertTrue(sessionCache.getSessionIds().contains(getKeyByIndex(newEngines, 1)));
|
||||||
|
|
||||||
|
Assertions.assertTrue(sessionCache.expireOldestSession());
|
||||||
|
|
||||||
|
Assertions.assertEquals(3, sessionCache.getSessionIds().size());
|
||||||
|
Assertions.assertTrue(sessionCache.getSessionIds().contains(getKeyByIndex(initialEngines, 2)));
|
||||||
|
Assertions.assertTrue(sessionCache.getSessionIds().contains(getKeyByIndex(newEngines, 0)));
|
||||||
|
Assertions.assertTrue(sessionCache.getSessionIds().contains(getKeyByIndex(newEngines, 1)));
|
||||||
|
|
||||||
|
Assertions.assertTrue(sessionCache.expireOldestSession());
|
||||||
|
Assertions.assertTrue(sessionCache.expireOldestSession());
|
||||||
|
Assertions.assertTrue(sessionCache.expireOldestSession());
|
||||||
|
Assertions.assertFalse(sessionCache.expireOldestSession());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void producerAddTest() {
|
||||||
|
ExplicitExpirySessionCacheDecorator maxSizeSessionCacheDecorator = new ExplicitExpirySessionCacheDecorator(new PassiveExpiringSessionCache());
|
||||||
|
ValidationEngine producedEngine = mock(ValidationEngine.class);
|
||||||
|
String sessionId = maxSizeSessionCacheDecorator.cacheSession(() -> {
|
||||||
|
return producedEngine;
|
||||||
|
});
|
||||||
|
Assertions.assertEquals(1, maxSizeSessionCacheDecorator.getSessionIds().size());
|
||||||
|
Assertions.assertSame(producedEngine, maxSizeSessionCacheDecorator.fetchSessionValidatorEngine(sessionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getKeyByIndex(LinkedHashMap<String, ValidationEngine> engineMap, int index) {
|
private String getKeyByIndex(LinkedHashMap<String, ValidationEngine> engineMap, int index) {
|
||||||
|
|
Loading…
Reference in New Issue