From 7d68b7460242db67ca43438e4a73d30ffd8f1fee Mon Sep 17 00:00:00 2001 From: Le Thanh Date: Wed, 6 Nov 2024 09:28:53 +0700 Subject: [PATCH] Add new LocalCachedMapOptions.readMode setting and new ReconnectionStrategy option RELOAD Signed-off-by: Le Thanh --- .../src/main/java/org/redisson/Redisson.java | 1 + .../org/redisson/RedissonLocalCachedMap.java | 42 ++++++++++++++----- .../java/org/redisson/RedissonReactive.java | 1 + .../main/java/org/redisson/RedissonRx.java | 1 + .../redisson/api/LocalCachedMapOptions.java | 42 ++++++++++++++++++- .../org/redisson/api/RLocalCachedMap.java | 7 ++++ .../api/options/LocalCachedMapOptions.java | 32 +++++++++++++- .../api/options/LocalCachedMapParams.java | 19 +++++++++ .../redisson/cache/LocalCacheListener.java | 4 ++ .../RedissonTransactionalLocalCachedMap.java | 5 +++ 10 files changed, 141 insertions(+), 13 deletions(-) diff --git a/redisson/src/main/java/org/redisson/Redisson.java b/redisson/src/main/java/org/redisson/Redisson.java index 57456191f..6fd0bab34 100755 --- a/redisson/src/main/java/org/redisson/Redisson.java +++ b/redisson/src/main/java/org/redisson/Redisson.java @@ -363,6 +363,7 @@ public final class Redisson implements RedissonClient { .cacheProvider(LocalCachedMapOptions.CacheProvider.valueOf(params.getCacheProvider().toString())) .cacheSize(params.getCacheSize()) .storeMode(LocalCachedMapOptions.StoreMode.valueOf(params.getStoreMode().toString())) + .readMode(LocalCachedMapOptions.ReadMode.valueOf(params.getReadMode().toString())) .evictionPolicy(LocalCachedMapOptions.EvictionPolicy.valueOf(params.getEvictionPolicy().toString())) .maxIdle(params.getMaxIdleInMillis()) .loader(params.getLoader()) diff --git a/redisson/src/main/java/org/redisson/RedissonLocalCachedMap.java b/redisson/src/main/java/org/redisson/RedissonLocalCachedMap.java index 9c5859dd6..b5be60491 100644 --- a/redisson/src/main/java/org/redisson/RedissonLocalCachedMap.java +++ b/redisson/src/main/java/org/redisson/RedissonLocalCachedMap.java @@ -58,6 +58,7 @@ public class RedissonLocalCachedMap extends RedissonMap implements R private int invalidateEntryOnChange; private SyncStrategy syncStrategy; private LocalCachedMapOptions.StoreMode storeMode; + private LocalCachedMapOptions.ReadMode readMode; private boolean storeCacheMiss; private boolean isUseObjectAsCacheKey; @@ -84,6 +85,7 @@ public class RedissonLocalCachedMap extends RedissonMap implements R } syncStrategy = options.getSyncStrategy(); storeMode = options.getStoreMode(); + readMode = options.getReadMode(); storeCacheMiss = options.isStoreCacheMiss(); isUseObjectAsCacheKey = options.isUseObjectAsCacheKey(); localCacheView = new LocalCacheView<>(options, this); @@ -100,6 +102,11 @@ public class RedissonLocalCachedMap extends RedissonMap implements R return new CacheValue(key, value); } + @Override + protected void reloadCache() { + RedissonLocalCachedMap.this.reloadCache(); + } + }; listener.add(cache, cacheKeyMap); instanceId = listener.getInstanceId(); @@ -216,7 +223,7 @@ public class RedissonLocalCachedMap extends RedissonMap implements R @Override public RFuture sizeAsync() { - if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE) { + if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE || readMode == LocalCachedMapOptions.ReadMode.LOCALCACHE) { return new CompletableFutureWrapper<>(cache.size()); } return super.sizeAsync(); @@ -229,7 +236,7 @@ public class RedissonLocalCachedMap extends RedissonMap implements R CacheKey cacheKey = localCacheView.toCacheKey(key); CacheValue cacheValue = cache.get(cacheKey); if (cacheValue == null) { - if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE) { + if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE || readMode == LocalCachedMapOptions.ReadMode.LOCALCACHE) { if (hasNoLoader()) { return new CompletableFutureWrapper<>(false); } @@ -276,7 +283,7 @@ public class RedissonLocalCachedMap extends RedissonMap implements R CacheValue cacheValue = new CacheValue(null, value); if (!cache.containsValue(cacheValue)) { - if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE) { + if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE || readMode == LocalCachedMapOptions.ReadMode.LOCALCACHE) { return new CompletableFutureWrapper<>(false); } @@ -295,7 +302,7 @@ public class RedissonLocalCachedMap extends RedissonMap implements R return new CompletableFutureWrapper<>((V) cacheValue.getValue()); } - if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE) { + if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE || readMode == LocalCachedMapOptions.ReadMode.LOCALCACHE) { if (hasNoLoader()) { return new CompletableFutureWrapper((Void) null); } @@ -672,7 +679,7 @@ public class RedissonLocalCachedMap extends RedissonMap implements R } } - if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE) { + if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE || readMode == LocalCachedMapOptions.ReadMode.LOCALCACHE) { if (hasNoLoader()) { return new CompletableFutureWrapper<>(result); } @@ -889,7 +896,7 @@ public class RedissonLocalCachedMap extends RedissonMap implements R result.add((V) value.getValue()); } - if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE) { + if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE || readMode == LocalCachedMapOptions.ReadMode.LOCALCACHE) { return new CompletableFutureWrapper<>(result); } @@ -932,7 +939,7 @@ public class RedissonLocalCachedMap extends RedissonMap implements R result.put((K) value.getKey(), (V) value.getValue()); } - if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE) { + if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE || readMode == LocalCachedMapOptions.ReadMode.LOCALCACHE) { return new CompletableFutureWrapper<>(result); } @@ -957,6 +964,19 @@ public class RedissonLocalCachedMap extends RedissonMap implements R } } + @Override + public void reloadCache() { + Set existingCacheKeys = new HashSet<>(cache.keySet()); + for (Entry entry : super.entrySet(null, 10)) { + CacheKey cacheKey = localCacheView.toCacheKey(entry.getKey()); + cachePut(cacheKey, entry.getKey(), entry.getValue()); + existingCacheKeys.remove(cacheKey); + } + for (CacheKey cacheKey : existingCacheKeys) { + cacheRemove(cacheKey); + } + } + @Override public void preloadCache(int count) { for (Entry entry : super.entrySet(count)) { @@ -988,7 +1008,7 @@ public class RedissonLocalCachedMap extends RedissonMap implements R result.add(new AbstractMap.SimpleEntry((K) value.getKey(), (V) value.getValue())); } - if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE) { + if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE || readMode == LocalCachedMapOptions.ReadMode.LOCALCACHE) { return new CompletableFutureWrapper<>(result); } @@ -1322,7 +1342,7 @@ public class RedissonLocalCachedMap extends RedissonMap implements R @Override public Set keySet(String pattern, int count) { - if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE) { + if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE || readMode == LocalCachedMapOptions.ReadMode.LOCALCACHE) { return cachedKeySet(); } return super.keySet(pattern, count); @@ -1330,7 +1350,7 @@ public class RedissonLocalCachedMap extends RedissonMap implements R @Override public Collection values(String keyPattern, int count) { - if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE) { + if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE || readMode == LocalCachedMapOptions.ReadMode.LOCALCACHE) { return cachedValues(); } return super.values(keyPattern, count); @@ -1338,7 +1358,7 @@ public class RedissonLocalCachedMap extends RedissonMap implements R @Override public Set> entrySet(String keyPattern, int count) { - if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE) { + if (storeMode == LocalCachedMapOptions.StoreMode.LOCALCACHE || readMode == LocalCachedMapOptions.ReadMode.LOCALCACHE) { return cachedEntrySet(); } return super.entrySet(keyPattern, count); diff --git a/redisson/src/main/java/org/redisson/RedissonReactive.java b/redisson/src/main/java/org/redisson/RedissonReactive.java index eb474de97..a169ea9e5 100644 --- a/redisson/src/main/java/org/redisson/RedissonReactive.java +++ b/redisson/src/main/java/org/redisson/RedissonReactive.java @@ -1160,6 +1160,7 @@ public class RedissonReactive implements RedissonReactiveClient { .cacheProvider(LocalCachedMapOptions.CacheProvider.valueOf(params.getCacheProvider().toString())) .cacheSize(params.getCacheSize()) .storeMode(LocalCachedMapOptions.StoreMode.valueOf(params.getStoreMode().toString())) + .readMode(LocalCachedMapOptions.ReadMode.valueOf(params.getReadMode().toString())) .evictionPolicy(LocalCachedMapOptions.EvictionPolicy.valueOf(params.getEvictionPolicy().toString())) .maxIdle(params.getMaxIdleInMillis()) .loader(params.getLoader()) diff --git a/redisson/src/main/java/org/redisson/RedissonRx.java b/redisson/src/main/java/org/redisson/RedissonRx.java index 5d3cfa6d0..ed7627a6a 100644 --- a/redisson/src/main/java/org/redisson/RedissonRx.java +++ b/redisson/src/main/java/org/redisson/RedissonRx.java @@ -1136,6 +1136,7 @@ public class RedissonRx implements RedissonRxClient { .cacheProvider(LocalCachedMapOptions.CacheProvider.valueOf(params.getCacheProvider().toString())) .cacheSize(params.getCacheSize()) .storeMode(LocalCachedMapOptions.StoreMode.valueOf(params.getStoreMode().toString())) + .readMode(LocalCachedMapOptions.ReadMode.valueOf(params.getReadMode().toString())) .evictionPolicy(LocalCachedMapOptions.EvictionPolicy.valueOf(params.getEvictionPolicy().toString())) .maxIdle(params.getMaxIdleInMillis()) .loader(params.getLoader()) diff --git a/redisson/src/main/java/org/redisson/api/LocalCachedMapOptions.java b/redisson/src/main/java/org/redisson/api/LocalCachedMapOptions.java index 07a7f2b3a..091ef48ab 100644 --- a/redisson/src/main/java/org/redisson/api/LocalCachedMapOptions.java +++ b/redisson/src/main/java/org/redisson/api/LocalCachedMapOptions.java @@ -57,7 +57,12 @@ public class LocalCachedMapOptions extends MapOptions { * if LocalCachedMap instance has been disconnected less than 10 minutes * or whole local cache will be cleaned otherwise. */ - LOAD + LOAD, + + /** + * Reload local cache if map instance connect/disconnected. + */ + RELOAD } @@ -132,6 +137,20 @@ public class LocalCachedMapOptions extends MapOptions { } + public enum ReadMode { + + /** + * Read data only in local cache. + */ + LOCALCACHE, + + /** + * Read data in Redis if not found in local cache. + */ + LOCALCACHE_REDIS + + } + public enum ExpirationEventPolicy { /** @@ -159,6 +178,7 @@ public class LocalCachedMapOptions extends MapOptions { private long maxIdleInMillis; private CacheProvider cacheProvider; private StoreMode storeMode; + private ReadMode readMode; private boolean storeCacheMiss; private ExpirationEventPolicy expirationEventPolicy; private boolean useObjectAsCacheKey; @@ -176,6 +196,7 @@ public class LocalCachedMapOptions extends MapOptions { this.maxIdleInMillis = copy.maxIdleInMillis; this.cacheProvider = copy.cacheProvider; this.storeMode = copy.storeMode; + this.readMode = copy.readMode; this.storeCacheMiss = copy.storeCacheMiss; this.useObjectAsCacheKey = copy.useObjectAsCacheKey; } @@ -207,6 +228,7 @@ public class LocalCachedMapOptions extends MapOptions { .reconnectionStrategy(ReconnectionStrategy.NONE) .cacheProvider(CacheProvider.REDISSON) .storeMode(StoreMode.LOCALCACHE_REDIS) + .readMode(ReadMode.LOCALCACHE_REDIS) .syncStrategy(SyncStrategy.INVALIDATE) .storeCacheMiss(false) .useObjectAsCacheKey(false) @@ -263,6 +285,7 @@ public class LocalCachedMapOptions extends MapOptions { * @param reconnectionStrategy *

CLEAR - clear local cache if map instance has been disconnected for a while. *

LOAD - store invalidated entry hash in invalidation log for 10 minutes. Cache keys for stored invalidated entry hashes will be removed if LocalCachedMap instance has been disconnected less than 10 minutes or whole cache will be cleaned otherwise + *

RELOAD -

NONE - Reload local cache if map instance connect/disconnected. *

NONE - Default. No reconnection handling * @return LocalCachedMapOptions instance */ @@ -364,6 +387,10 @@ public class LocalCachedMapOptions extends MapOptions { return storeMode; } + public ReadMode getReadMode() { + return readMode; + } + /** * Defines store mode of cache data. * @@ -377,6 +404,19 @@ public class LocalCachedMapOptions extends MapOptions { return this; } + /** + * Defines read mode of cache data. + * + * @param readMode + *

LOCALCACHE - read data in local cache only. + *

LOCALCACHE_REDIS - read data in Redis if not found in local cache. + * @return LocalCachedMapOptions instance + */ + public LocalCachedMapOptions readMode(ReadMode readMode) { + this.readMode = readMode; + return this; + } + /** * Defines Cache provider used as local cache store. * diff --git a/redisson/src/main/java/org/redisson/api/RLocalCachedMap.java b/redisson/src/main/java/org/redisson/api/RLocalCachedMap.java index 8d0749790..4f605ba38 100644 --- a/redisson/src/main/java/org/redisson/api/RLocalCachedMap.java +++ b/redisson/src/main/java/org/redisson/api/RLocalCachedMap.java @@ -39,6 +39,13 @@ public interface RLocalCachedMap extends RMap { */ void preloadCache(); + /** + * Reload the cached entries. Not guaranteed to load ALL values, but statistically + * will reload approximately all (all if no concurrent mutating activity). + * Entries are loaded in a batch with size of 10 elements. + */ + void reloadCache(); + /** * Pre-warm the cached entries. Not guaranteed to load ALL values, but statistically * will preload approximately all (all if no concurrent mutating activity) diff --git a/redisson/src/main/java/org/redisson/api/options/LocalCachedMapOptions.java b/redisson/src/main/java/org/redisson/api/options/LocalCachedMapOptions.java index 7efe44702..f13b880ae 100644 --- a/redisson/src/main/java/org/redisson/api/options/LocalCachedMapOptions.java +++ b/redisson/src/main/java/org/redisson/api/options/LocalCachedMapOptions.java @@ -50,7 +50,12 @@ public interface LocalCachedMapOptions extends ExMapOptions extends ExMapOptions extends ExMapOptionsCLEAR - clear local cache if map instance has been disconnected for a while. *

LOAD - store invalidated entry hash in invalidation log for 10 minutes. Cache keys for stored invalidated entry hashes will be removed if LocalCachedMap instance has been disconnected less than 10 minutes or whole cache will be cleaned otherwise + *

RELOAD - Reload local cache if map instance connect/disconnected. *

NONE - Default. No reconnection handling * @return LocalCachedMapOptions instance */ @@ -228,6 +248,16 @@ public interface LocalCachedMapOptions extends ExMapOptions storeMode(StoreMode storeMode); + /** + * Defines read mode of cache data. + * + * @param readMode + *

LOCALCACHE - read data in local cache only. + *

LOCALCACHE_REDIS - read data in Redis if not found in local cache. + * @return LocalCachedMapOptions instance + */ + LocalCachedMapOptions readMode(LocalCachedMapOptions.ReadMode readMode); + /** * Defines Cache provider used as local cache store. * diff --git a/redisson/src/main/java/org/redisson/api/options/LocalCachedMapParams.java b/redisson/src/main/java/org/redisson/api/options/LocalCachedMapParams.java index c1c94504c..5b79898f9 100644 --- a/redisson/src/main/java/org/redisson/api/options/LocalCachedMapParams.java +++ b/redisson/src/main/java/org/redisson/api/options/LocalCachedMapParams.java @@ -36,6 +36,7 @@ public final class LocalCachedMapParams extends BaseMapOptions extends BaseMapOptionsCLEAR - clear local cache if map instance has been disconnected for a while. *

LOAD - store invalidated entry hash in invalidation log for 10 minutes. Cache keys for stored invalidated entry hashes will be removed if LocalCachedMap instance has been disconnected less than 10 minutes or whole cache will be cleaned otherwise + *

RELOAD - Reload local cache if map instance connect/disconnected. *

NONE - Default. No reconnection handling * @return LocalCachedMapOptions instance */ @@ -173,6 +175,10 @@ public final class LocalCachedMapParams extends BaseMapOptions extends BaseMapOptionsLOCALCACHE - read data in local cache only. + *

LOCALCACHE_REDIS - read data in Redis if not found in local cache. + * @return LocalCachedMapOptions instance + */ + public LocalCachedMapParams readMode(ReadMode readMode) { + this.readMode = readMode; + return this; + } + /** * Defines Cache provider used as local cache store. * diff --git a/redisson/src/main/java/org/redisson/cache/LocalCacheListener.java b/redisson/src/main/java/org/redisson/cache/LocalCacheListener.java index 3e9c84f5d..f2e760608 100644 --- a/redisson/src/main/java/org/redisson/cache/LocalCacheListener.java +++ b/redisson/src/main/java/org/redisson/cache/LocalCacheListener.java @@ -293,6 +293,9 @@ public abstract class LocalCacheListener { loadAfterReconnection(); } + if (options.getReconnectionStrategy() == ReconnectionStrategy.RELOAD) { + reloadCache(); + } } public void notifyUpdate(CacheValue value) { @@ -353,6 +356,7 @@ public abstract class LocalCacheListener { } protected abstract CacheValue updateCache(ByteBuf keyBuf, ByteBuf valueBuf) throws IOException; + protected abstract void reloadCache(); private void disableKeys(final String requestId, final Set keys, long timeout) { for (CacheKey key : keys) { diff --git a/redisson/src/main/java/org/redisson/transaction/RedissonTransactionalLocalCachedMap.java b/redisson/src/main/java/org/redisson/transaction/RedissonTransactionalLocalCachedMap.java index 7a48bd8ec..4d853bc7a 100644 --- a/redisson/src/main/java/org/redisson/transaction/RedissonTransactionalLocalCachedMap.java +++ b/redisson/src/main/java/org/redisson/transaction/RedissonTransactionalLocalCachedMap.java @@ -50,6 +50,11 @@ public class RedissonTransactionalLocalCachedMap extends RedissonTransacti throw new UnsupportedOperationException("preloadCache method is not supported in transaction"); } + @Override + public void reloadCache() { + throw new UnsupportedOperationException("reloadCache method is not supported in transaction"); + } + @Override public void preloadCache(int count) { throw new UnsupportedOperationException("preloadCache method is not supported in transaction");