Skip to content

Commit ce210ea

Browse files
authored
Adding Cache class to CacheConfig (#3942)
* adding cacheclass to cacheconfig * - add cachefactory test * - revert connection ctors to public - udpate some tests with UnifiedJedis.getCache - add ping to flaky tests * remove unnecessary anonymous types * change ctor access modifiers * fix test name * make cachefactory methods static * removing pings due to still flaky with inv messages * - drop CustomCache in tests and use TestCache - check null cacheable issue with defaultcache - support both ctors in custom cache classes regarding to value of cacheconfig.cacheable * remove unncessary maxsize * - remove inline anonymious
1 parent 1d213bb commit ce210ea

15 files changed

+233
-184
lines changed

Diff for: src/main/java/redis/clients/jedis/JedisCluster.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import redis.clients.jedis.providers.ClusterConnectionProvider;
1313
import redis.clients.jedis.csc.Cache;
1414
import redis.clients.jedis.csc.CacheConfig;
15-
import redis.clients.jedis.csc.CacheProvider;
15+
import redis.clients.jedis.csc.CacheFactory;
1616
import redis.clients.jedis.util.JedisClusterCRC16;
1717

1818
public class JedisCluster extends UnifiedJedis {
@@ -223,7 +223,7 @@ private JedisCluster(ClusterConnectionProvider provider, int maxAttempts, Durati
223223

224224
@Experimental
225225
public JedisCluster(Set<HostAndPort> hnp, JedisClientConfig jedisClientConfig, CacheConfig cacheConfig) {
226-
this(hnp, jedisClientConfig, new CacheProvider().getCache(cacheConfig));
226+
this(hnp, jedisClientConfig, CacheFactory.getCache(cacheConfig));
227227
}
228228

229229
@Experimental

Diff for: src/main/java/redis/clients/jedis/JedisPooled.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import redis.clients.jedis.annots.Experimental;
1111
import redis.clients.jedis.csc.Cache;
1212
import redis.clients.jedis.csc.CacheConfig;
13-
import redis.clients.jedis.csc.CacheProvider;
13+
import redis.clients.jedis.csc.CacheFactory;
1414
import redis.clients.jedis.providers.PooledConnectionProvider;
1515
import redis.clients.jedis.util.JedisURIHelper;
1616
import redis.clients.jedis.util.Pool;
@@ -81,7 +81,7 @@ public JedisPooled(final HostAndPort hostAndPort, final JedisClientConfig client
8181

8282
@Experimental
8383
public JedisPooled(final HostAndPort hostAndPort, final JedisClientConfig clientConfig, CacheConfig cacheConfig) {
84-
this(hostAndPort, clientConfig, new CacheProvider().getCache(cacheConfig));
84+
this(hostAndPort, clientConfig, CacheFactory.getCache(cacheConfig));
8585
}
8686

8787
@Experimental
@@ -392,7 +392,7 @@ public JedisPooled(final HostAndPort hostAndPort, final JedisClientConfig client
392392
@Experimental
393393
public JedisPooled(final HostAndPort hostAndPort, final JedisClientConfig clientConfig, CacheConfig cacheConfig,
394394
final GenericObjectPoolConfig<Connection> poolConfig) {
395-
this(hostAndPort, clientConfig, new CacheProvider().getCache(cacheConfig), poolConfig);
395+
this(hostAndPort, clientConfig, CacheFactory.getCache(cacheConfig), poolConfig);
396396
}
397397

398398
@Experimental

Diff for: src/main/java/redis/clients/jedis/JedisSentineled.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import redis.clients.jedis.annots.Experimental;
66
import redis.clients.jedis.csc.Cache;
77
import redis.clients.jedis.csc.CacheConfig;
8-
import redis.clients.jedis.csc.CacheProvider;
8+
import redis.clients.jedis.csc.CacheFactory;
99
import redis.clients.jedis.providers.SentineledConnectionProvider;
1010

1111
public class JedisSentineled extends UnifiedJedis {
@@ -19,7 +19,7 @@ public JedisSentineled(String masterName, final JedisClientConfig masterClientCo
1919
@Experimental
2020
public JedisSentineled(String masterName, final JedisClientConfig masterClientConfig, CacheConfig cacheConfig,
2121
Set<HostAndPort> sentinels, final JedisClientConfig sentinelClientConfig) {
22-
this(masterName, masterClientConfig, new CacheProvider().getCache(cacheConfig),
22+
this(masterName, masterClientConfig, CacheFactory.getCache(cacheConfig),
2323
sentinels, sentinelClientConfig);
2424
}
2525

Diff for: src/main/java/redis/clients/jedis/UnifiedJedis.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import redis.clients.jedis.csc.Cache;
2323
import redis.clients.jedis.csc.CacheConfig;
2424
import redis.clients.jedis.csc.CacheConnection;
25-
import redis.clients.jedis.csc.CacheProvider;
25+
import redis.clients.jedis.csc.CacheFactory;
2626
import redis.clients.jedis.exceptions.JedisException;
2727
import redis.clients.jedis.executors.*;
2828
import redis.clients.jedis.gears.TFunctionListParams;
@@ -100,7 +100,7 @@ public UnifiedJedis(HostAndPort hostAndPort, JedisClientConfig clientConfig) {
100100

101101
@Experimental
102102
public UnifiedJedis(HostAndPort hostAndPort, JedisClientConfig clientConfig, CacheConfig cacheConfig) {
103-
this(hostAndPort, clientConfig, new CacheProvider().getCache(cacheConfig));
103+
this(hostAndPort, clientConfig, CacheFactory.getCache(cacheConfig));
104104
}
105105

106106
@Experimental

Diff for: src/main/java/redis/clients/jedis/csc/CacheConfig.java

+13-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ public class CacheConfig {
55
private int maxSize;
66
private Cacheable cacheable;
77
private EvictionPolicy evictionPolicy;
8+
private Class cacheClass;
89

910
public int getMaxSize() {
1011
return maxSize;
@@ -18,14 +19,19 @@ public EvictionPolicy getEvictionPolicy() {
1819
return evictionPolicy;
1920
}
2021

22+
public Class getCacheClass() {
23+
return cacheClass;
24+
}
2125
public static Builder builder() {
2226
return new Builder();
2327
}
2428

2529
public static class Builder {
26-
private int maxSize;
30+
private final int DEFAULT_MAX_SIZE = 10000;
31+
private int maxSize = DEFAULT_MAX_SIZE;
2732
private Cacheable cacheable = DefaultCacheable.INSTANCE;
2833
private EvictionPolicy evictionPolicy;
34+
private Class cacheClass;
2935

3036
public Builder maxSize(int maxSize) {
3137
this.maxSize = maxSize;
@@ -42,11 +48,17 @@ public Builder cacheable(Cacheable cacheable) {
4248
return this;
4349
}
4450

51+
public Builder cacheClass(Class cacheClass) {
52+
this.cacheClass = cacheClass;
53+
return this;
54+
}
55+
4556
public CacheConfig build() {
4657
CacheConfig cacheConfig = new CacheConfig();
4758
cacheConfig.maxSize = this.maxSize;
4859
cacheConfig.cacheable = this.cacheable;
4960
cacheConfig.evictionPolicy = this.evictionPolicy;
61+
cacheConfig.cacheClass = this.cacheClass;
5062
return cacheConfig;
5163
}
5264
}
+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package redis.clients.jedis.csc;
2+
3+
import java.lang.reflect.Constructor;
4+
import java.lang.reflect.InvocationTargetException;
5+
import java.util.Arrays;
6+
7+
import redis.clients.jedis.exceptions.JedisCacheException;
8+
9+
public final class CacheFactory {
10+
11+
public static Cache getCache(CacheConfig config) {
12+
if (config.getCacheClass() == null) {
13+
if (config.getCacheable() == null) {
14+
throw new JedisCacheException("Cacheable is required to create the default cache!");
15+
}
16+
return new DefaultCache(config.getMaxSize(), config.getCacheable(), getEvictionPolicy(config));
17+
}
18+
return instantiateCustomCache(config);
19+
}
20+
21+
private static Cache instantiateCustomCache(CacheConfig config) {
22+
try {
23+
if (config.getCacheable() != null) {
24+
Constructor ctorWithCacheable = findConstructorWithCacheable(config.getCacheClass());
25+
if (ctorWithCacheable != null) {
26+
return (Cache) ctorWithCacheable.newInstance(config.getMaxSize(), getEvictionPolicy(config), config.getCacheable());
27+
}
28+
}
29+
Constructor ctor = getConstructor(config.getCacheClass());
30+
return (Cache) ctor.newInstance(config.getMaxSize(), getEvictionPolicy(config));
31+
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
32+
| SecurityException e) {
33+
throw new JedisCacheException("Failed to insantiate custom cache type!", e);
34+
}
35+
}
36+
37+
private static Constructor findConstructorWithCacheable(Class customCacheType) {
38+
return Arrays.stream(customCacheType.getConstructors())
39+
.filter(ctor -> Arrays.equals(ctor.getParameterTypes(), new Class[] { int.class, EvictionPolicy.class, Cacheable.class }))
40+
.findFirst().orElse(null);
41+
}
42+
43+
private static Constructor getConstructor(Class customCacheType) {
44+
try {
45+
return customCacheType.getConstructor(int.class, EvictionPolicy.class);
46+
} catch (NoSuchMethodException e) {
47+
String className = customCacheType.getName();
48+
throw new JedisCacheException(String.format(
49+
"Failed to find compatible constructor for custom cache type! Provide one of these;"
50+
// give hints about the compatible constructors
51+
+ "\n - %s(int maxSize, EvictionPolicy evictionPolicy)\n - %s(int maxSize, EvictionPolicy evictionPolicy, Cacheable cacheable)",
52+
className, className), e);
53+
}
54+
}
55+
56+
private static EvictionPolicy getEvictionPolicy(CacheConfig config) {
57+
if (config.getEvictionPolicy() == null) {
58+
// It will be default to LRUEviction, until we have other eviction implementations
59+
return new LRUEviction(config.getMaxSize());
60+
}
61+
return config.getEvictionPolicy();
62+
}
63+
}

Diff for: src/main/java/redis/clients/jedis/csc/CacheProvider.java

-23
This file was deleted.

Diff for: src/main/java/redis/clients/jedis/csc/DefaultCache.java

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ protected DefaultCache(int maximumSize, Cacheable cacheable) {
2121
this(maximumSize, new HashMap<CacheKey, CacheEntry>(), cacheable, new LRUEviction(maximumSize));
2222
}
2323

24+
protected DefaultCache(int maximumSize, Cacheable cacheable, EvictionPolicy evictionPolicy) {
25+
this(maximumSize, new HashMap<CacheKey, CacheEntry>(), cacheable, evictionPolicy);
26+
}
27+
2428
protected DefaultCache(int maximumSize, Map<CacheKey, CacheEntry> map, Cacheable cacheable, EvictionPolicy evictionPolicy) {
2529
super(maximumSize, cacheable);
2630
this.cache = map;
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
package redis.clients.jedis.csc;
22

33
import static java.util.Collections.singleton;
4-
import static org.hamcrest.MatcherAssert.assertThat;
54
import static org.junit.Assert.assertEquals;
65

7-
import java.util.HashMap;
8-
import java.util.Map;
9-
import org.hamcrest.Matchers;
106
import org.junit.Test;
117

128
import redis.clients.jedis.JedisPooled;
@@ -15,73 +11,69 @@
1511

1612
public class AllowAndDenyListCacheableTest extends ClientSideCacheTestBase {
1713

18-
private static Cache createTestCache(Map<CacheKey, CacheEntry> map, Cacheable cacheable) {
19-
Cache mapCache = new TestCache(map, cacheable);
20-
return mapCache;
14+
private static CacheConfig createConfig(Cacheable cacheable) {
15+
return CacheConfig.builder().cacheable(cacheable).cacheClass(TestCache.class).build();
2116
}
2217

2318
@Test
2419
public void none() {
25-
HashMap<CacheKey, CacheEntry> map = new HashMap<>();
2620
try (JedisPooled jedis = new JedisPooled(hnp, clientConfig.get(),
27-
createTestCache(map, new AllowAndDenyListWithStringKeys(null, null, null, null)),
28-
singleConnectionPoolConfig.get())) {
21+
createConfig(new AllowAndDenyListWithStringKeys(null, null, null, null)), singleConnectionPoolConfig.get())) {
22+
Cache cache = jedis.getCache();
2923
control.set("foo", "bar");
30-
assertThat(map, Matchers.aMapWithSize(0));
24+
assertEquals(0, cache.getSize());
3125
assertEquals("bar", jedis.get("foo"));
32-
assertThat(map, Matchers.aMapWithSize(1));
26+
assertEquals(1, cache.getSize());
3327
}
3428
}
3529

3630
@Test
3731
public void whiteListCommand() {
38-
HashMap<CacheKey, CacheEntry> map = new HashMap<>();
3932
try (JedisPooled jedis = new JedisPooled(hnp, clientConfig.get(),
40-
createTestCache(map, new AllowAndDenyListWithStringKeys(singleton(Protocol.Command.GET), null, null, null)),
33+
createConfig(new AllowAndDenyListWithStringKeys(singleton(Protocol.Command.GET), null, null, null)),
4134
singleConnectionPoolConfig.get())) {
35+
Cache cache = jedis.getCache();
4236
control.set("foo", "bar");
43-
assertThat(map, Matchers.aMapWithSize(0));
37+
assertEquals(0, cache.getSize());
4438
assertEquals("bar", jedis.get("foo"));
45-
assertThat(map, Matchers.aMapWithSize(1));
39+
assertEquals(1, cache.getSize());
4640
}
4741
}
4842

4943
@Test
5044
public void blackListCommand() {
51-
HashMap<CacheKey, CacheEntry> map = new HashMap<>();
5245
try (JedisPooled jedis = new JedisPooled(hnp, clientConfig.get(),
53-
createTestCache(map, new AllowAndDenyListWithStringKeys(null, singleton(Protocol.Command.GET), null, null)),
46+
createConfig(new AllowAndDenyListWithStringKeys(null, singleton(Protocol.Command.GET), null, null)),
5447
singleConnectionPoolConfig.get())) {
48+
Cache cache = jedis.getCache();
5549
control.set("foo", "bar");
56-
assertThat(map, Matchers.aMapWithSize(0));
50+
assertEquals(0, cache.getSize());
5751
assertEquals("bar", jedis.get("foo"));
58-
assertThat(map, Matchers.aMapWithSize(0));
52+
assertEquals(0, cache.getSize());
5953
}
6054
}
6155

6256
@Test
6357
public void whiteListKey() {
64-
HashMap<CacheKey, CacheEntry> map = new HashMap<>();
6558
try (JedisPooled jedis = new JedisPooled(hnp, clientConfig.get(),
66-
createTestCache(map, new AllowAndDenyListWithStringKeys(null, null, singleton("foo"), null)),
67-
singleConnectionPoolConfig.get())) {
59+
createConfig(new AllowAndDenyListWithStringKeys(null, null, singleton("foo"), null)), singleConnectionPoolConfig.get())) {
6860
control.set("foo", "bar");
69-
assertThat(map, Matchers.aMapWithSize(0));
61+
Cache cache = jedis.getCache();
62+
assertEquals(0, cache.getSize());
7063
assertEquals("bar", jedis.get("foo"));
71-
assertThat(map, Matchers.aMapWithSize(1));
64+
assertEquals(1, cache.getSize());
7265
}
7366
}
7467

7568
@Test
7669
public void blackListKey() {
77-
HashMap<CacheKey, CacheEntry> map = new HashMap<>();
7870
try (JedisPooled jedis = new JedisPooled(hnp, clientConfig.get(),
79-
createTestCache(map, new AllowAndDenyListWithStringKeys(null, null, null, singleton("foo"))),
80-
singleConnectionPoolConfig.get())) {
71+
createConfig(new AllowAndDenyListWithStringKeys(null, null, null, singleton("foo"))), singleConnectionPoolConfig.get())) {
72+
Cache cache = jedis.getCache();
8173
control.set("foo", "bar");
82-
assertThat(map, Matchers.aMapWithSize(0));
74+
assertEquals(0, cache.getSize());
8375
assertEquals("bar", jedis.get("foo"));
84-
assertThat(map, Matchers.aMapWithSize(0));
76+
assertEquals(0, cache.getSize());
8577
}
8678
}
8779
}

0 commit comments

Comments
 (0)