Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public static CaffeineCacheConfig getCaffeineConfig() {
var config = Mockito.mock(CaffeineCacheConfig.class);
var telemetry = Mockito.mock(CaffeineCacheTelemetryConfig.class);
when(config.telemetry()).thenReturn(telemetry);
when(config.enabled()).thenReturn(true);
when(config.maximumSize()).thenReturn(100_000L);
when(config.expireAfterAccess()).thenReturn(null);
when(config.expireAfterWrite()).thenReturn(null);
Expand All @@ -37,6 +38,7 @@ public static CaffeineCacheConfig getCaffeineConfig() {

public static RedisCacheConfig getRedisConfig() {
var config = Mockito.mock(RedisCacheConfig.class);
when(config.enabled()).thenReturn(true);
when(config.keyPrefix()).thenReturn("pref");
when(config.telemetry()).thenReturn(new $RedisCacheTelemetryConfig_ConfigValueMapper.RedisCacheTelemetryConfig_Impl(
new $RedisCacheTelemetryConfig_RedisCacheLoggingConfig_ConfigValueMapper.RedisCacheLoggingConfig_Defaults(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ public abstract class AbstractCaffeineCache<K, V> implements CaffeineCache<K, V>

private final Cache<K, V> caffeine;
private final CaffeineCacheTelemetry telemetry;
private final boolean enabled;

protected AbstractCaffeineCache(String cacheConfigPath,
CaffeineCacheConfig config,
CaffeineCacheFactory factory,
CaffeineCacheTelemetryFactory telemetryFactory) {
this.caffeine = factory.build(cacheConfigPath, config);
this.telemetry = telemetryFactory.get(cacheConfigPath, getClass(), config.telemetry());
this.enabled = config.enabled();
}

@Override
Expand All @@ -35,6 +37,9 @@ public V get(K key) {
if (key == null) {
return null;
}
if (!enabled) {
return null;
}

var observation = this.telemetry.observe(GET);
observation.observeKey(key);
Expand All @@ -55,6 +60,9 @@ public Map<K, V> get(Collection<K> keys) {
if (keys == null || keys.isEmpty()) {
return Collections.emptyMap();
}
if (!enabled) {
return Collections.emptyMap();
}

var observation = this.telemetry.observe(GET_MANY);
observation.observeKeys(keys);
Expand All @@ -72,6 +80,10 @@ public Map<K, V> get(Collection<K> keys) {

@Override
public Map<K, V> getAll() {
if (!enabled) {
return Collections.emptyMap();
}

var observation = this.telemetry.observe(GET_ALL);
try {
var values = Collections.unmodifiableMap(caffeine.asMap());
Expand All @@ -90,6 +102,9 @@ public V computeIfAbsent(K key, Function<K, @Nullable V> mappingFunction) {
if (key == null) {
return mappingFunction.apply(key);
}
if (!enabled) {
return mappingFunction.apply(key);
}

var observation = this.telemetry.observe(COMPUTE_IF_ABSENT);
observation.observeKey(key);
Expand All @@ -111,6 +126,9 @@ public Map<K, V> computeIfAbsent(Collection<K> keys, Function<Set<K>, Map<K, V>>
if (keys == null || keys.isEmpty()) {
return mappingFunction.apply(Collections.emptySet());
}
if (!enabled) {
return mappingFunction.apply(Set.copyOf(keys));
}

var observation = this.telemetry.observe(COMPUTE_IF_ABSENT_MANY);
observation.observeKeys(keys);
Expand All @@ -133,6 +151,9 @@ public V put(K key, V value) {
if (key == null || value == null) {
return value;
}
if (!enabled) {
return value;
}

var observation = this.telemetry.observe(PUT);
observation.observeKey(key);
Expand All @@ -153,6 +174,9 @@ public Map<K, V> put(Map<K, V> keyAndValues) {
if (keyAndValues == null || keyAndValues.isEmpty()) {
return Collections.emptyMap();
}
if (!enabled) {
return keyAndValues;
}

var observation = this.telemetry.observe(PUT_MANY);
observation.observeKeys(keyAndValues.keySet());
Expand All @@ -173,6 +197,9 @@ public void invalidate(K key) {
if (key == null) {
return;
}
if (!enabled) {
return;
}

var observation = this.telemetry.observe(INVALIDATE);
observation.observeKey(key);
Expand All @@ -191,6 +218,9 @@ public void invalidate(Collection<K> keys) {
if (keys == null || keys.isEmpty()) {
return;
}
if (!enabled) {
return;
}

var observation = this.telemetry.observe(INVALIDATE_MANY);
observation.observeKeys(keys);
Expand All @@ -206,6 +236,10 @@ public void invalidate(Collection<K> keys) {

@Override
public void invalidateAll() {
if (!enabled) {
return;
}

var observation = this.telemetry.observe(INVALIDATE_ALL);
try {
observation.observeKeys(List.of());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
@ConfigMapper
public interface CaffeineCacheConfig {

default boolean enabled() {
return true;
}

@Nullable
Duration expireAfterWrite();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public static CaffeineCacheConfig getConfig() {
var config = Mockito.mock(CaffeineCacheConfig.class);
var telemetry = Mockito.mock(CaffeineCacheTelemetryConfig.class);
when(config.telemetry()).thenReturn(telemetry);
when(config.enabled()).thenReturn(true);
when(config.maximumSize()).thenReturn(100_000L);
when(config.expireAfterAccess()).thenReturn(null);
when(config.expireAfterWrite()).thenReturn(null);
Expand All @@ -24,8 +25,14 @@ public static CaffeineCacheConfig getConfig() {
return config;
}
protected DummyCache createCache() {
return createCache(true);
}

protected DummyCache createCache(boolean enabled) {
try {
return new DummyCache(getConfig(), caffeineCacheFactory(null), defaultCaffeineCacheTelemetryFactory(null, null, null, null));
var config = getConfig();
when(config.enabled()).thenReturn(enabled);
return new DummyCache(config, caffeineCacheFactory(null), defaultCaffeineCacheTelemetryFactory(null, null, null, null));
} catch (Exception e) {
throw new IllegalStateException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
import org.junit.jupiter.api.TestInstance;
import io.koraframework.cache.caffeine.testdata.DummyCache;

import java.util.List;
import java.util.Map;
import java.util.Set;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class SyncCacheTests extends CacheRunner {

Expand Down Expand Up @@ -81,4 +85,27 @@ void getFromCacheWhenCacheInvalidateAll() {
final String fromCache = cache.get(key);
assertNull(fromCache);
}

@Test
void operationsAreDisabledWhenConfigDisabled() {
// given
var disabledCache = createCache(false);

// when
assertEquals("1", disabledCache.put("1", "1"));
assertEquals(Map.of("2", "2"), disabledCache.put(Map.of("2", "2")));

// then
assertNull(disabledCache.get("1"));
assertTrue(disabledCache.get(List.of("1", "2")).isEmpty());
assertTrue(disabledCache.getAll().isEmpty());

// when
assertEquals("3", disabledCache.computeIfAbsent("3", k -> "3"));
assertEquals(Map.of("4", "4"), disabledCache.computeIfAbsent(Set.of("4"), keys -> Map.of("4", "4")));

// then
assertNull(disabledCache.get("3"));
assertTrue(disabledCache.get(List.of("4")).isEmpty());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public abstract class AbstractRedisCache<K, V> implements RedisCache<K, V> {

private final RedisCacheClient redisClient;
private final RedisCacheTelemetry telemetry;
private final boolean enabled;

private final RedisCacheKeyMapper<K> keyMapper;
private final RedisCacheValueMapper<V> valueMapper;
Expand All @@ -45,6 +46,7 @@ protected AbstractRedisCache(String cacheConfigPath,
RedisCacheValueMapper<V> valueMapper) {
this.redisClient = redisClient;
this.telemetry = telemetryFactory.get(cacheConfigPath, getClass(), config.telemetry());
this.enabled = config.enabled();
this.keyMapper = keyMapper;
this.valueMapper = valueMapper;
this.expireAfterAccessMillis = (config.expireAfterAccess() == null)
Expand Down Expand Up @@ -74,6 +76,9 @@ public V get(K key) {
if (key == null) {
return null;
}
if (!enabled) {
return null;
}

var observation = this.telemetry.observe(Operation.GET);
return ScopedValue
Expand Down Expand Up @@ -107,6 +112,9 @@ public Map<K, V> get(Collection<K> keys) {
if (keys == null || keys.isEmpty()) {
return Collections.emptyMap();
}
if (!enabled) {
return Collections.emptyMap();
}

var observation = this.telemetry.observe(Operation.GET_MANY);
return ScopedValue
Expand Down Expand Up @@ -152,6 +160,9 @@ public V put(K key, V value) {
if (key == null || value == null) {
return null;
}
if (!enabled) {
return value;
}

var observation = this.telemetry.observe(Operation.PUT);
return ScopedValue
Expand Down Expand Up @@ -186,6 +197,9 @@ public Map<K, V> put(Map<K, V> keyAndValues) {
if (keyAndValues == null || keyAndValues.isEmpty()) {
return Collections.emptyMap();
}
if (!enabled) {
return keyAndValues;
}

var observation = this.telemetry.observe(Operation.PUT_MANY);
return ScopedValue
Expand Down Expand Up @@ -233,6 +247,9 @@ public V computeIfAbsent(K key, Function<K, @Nullable V> mappingFunction) {
if (key == null) {
return mappingFunction.apply(key);
}
if (!enabled) {
return mappingFunction.apply(key);
}

var observation = this.telemetry.observe(Operation.COMPUTE_IF_ABSENT);
return ScopedValue
Expand Down Expand Up @@ -290,6 +307,9 @@ public Map<K, V> computeIfAbsent(Collection<K> keys, Function<Set<K>, Map<K, V>>
if (keys == null || keys.isEmpty()) {
return mappingFunction.apply(Collections.emptySet());
}
if (!enabled) {
return mappingFunction.apply(Set.copyOf(keys));
}

var observation = this.telemetry.observe(Operation.COMPUTE_IF_ABSENT_MANY);
return ScopedValue
Expand Down Expand Up @@ -370,6 +390,9 @@ public void invalidate(K key) {
if (key == null) {
return;
}
if (!enabled) {
return;
}

var observation = this.telemetry.observe(Operation.INVALIDATE);
ScopedValue
Expand All @@ -395,6 +418,9 @@ public void invalidate(Collection<K> keys) {
if (keys == null || keys.isEmpty()) {
return;
}
if (!enabled) {
return;
}

var observation = this.telemetry.observe(Operation.INVALIDATE_MANY);
ScopedValue
Expand All @@ -420,6 +446,10 @@ public void invalidate(Collection<K> keys) {

@Override
public void invalidateAll() {
if (!enabled) {
return;
}

var observation = this.telemetry.observe(Operation.INVALIDATE_ALL);
ScopedValue
.where(Observation.VALUE, observation)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
@ConfigMapper
public interface RedisCacheConfig {

default boolean enabled() {
return true;
}

/**
* Key prefix allow to avoid key collision in single Redis database between multiple caches
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,19 @@ public abstract class CacheRunner extends Assertions implements LettuceRedisCach

public static RedisCacheConfig getConfig(@Nullable Duration expireWrite,
@Nullable Duration expireRead) {
return getConfig(expireWrite, expireRead, true);
}

public static RedisCacheConfig getConfig(@Nullable Duration expireWrite,
@Nullable Duration expireRead,
boolean enabled) {
return new RedisCacheConfig() {

@Override
public boolean enabled() {
return enabled;
}

@Override
public String keyPrefix() {
return PREFIX;
Expand Down Expand Up @@ -96,8 +107,12 @@ public LettuceTelemetryConfig telemetry() {
}

private DummyCache createDummyCache(RedisParams redisParams, Duration expireWrite, Duration expireRead) throws Exception {
return createDummyCache(redisParams, expireWrite, expireRead, true);
}

private DummyCache createDummyCache(RedisParams redisParams, Duration expireWrite, Duration expireRead, boolean enabled) throws Exception {
var lettuceClient = createLettuce(redisParams);
return new DummyCache(getConfig(expireWrite, expireRead), lettuceClient, defaultRedisCacheTelemetryFactory(null, null, null, null),
return new DummyCache(getConfig(expireWrite, expireRead, enabled), lettuceClient, defaultRedisCacheTelemetryFactory(null, null, null, null),
stringRedisCacheKeyMapper(), stringRedisCacheValueMapper());
}

Expand All @@ -112,4 +127,8 @@ protected DummyCache createCacheExpireWrite(RedisParams redisParams, Duration ex
protected DummyCache createCacheExpireRead(RedisParams redisParams, Duration expireRead) throws Exception {
return createDummyCache(redisParams, null, expireRead);
}

protected DummyCache createCacheDisabled(RedisParams redisParams) throws Exception {
return createDummyCache(redisParams, null, null, false);
}
}
Loading
Loading