diff --git a/redisson/src/main/java/org/redisson/Redisson.java b/redisson/src/main/java/org/redisson/Redisson.java index e50f820d7..a7f3cc0f8 100755 --- a/redisson/src/main/java/org/redisson/Redisson.java +++ b/redisson/src/main/java/org/redisson/Redisson.java @@ -374,6 +374,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 71b2c2b65..613348077 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; @@ -78,6 +79,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); @@ -94,6 +96,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(); @@ -213,7 +220,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(); @@ -226,7 +233,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); } @@ -273,7 +280,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); } @@ -292,7 +299,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); } @@ -669,7 +676,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); } @@ -921,7 +928,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); } @@ -964,7 +971,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); } @@ -989,6 +996,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)) { @@ -1020,7 +1040,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); } @@ -1354,7 +1374,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); @@ -1362,7 +1382,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); @@ -1370,7 +1390,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 3c2189f43..0b4157d0c 100644 --- a/redisson/src/main/java/org/redisson/RedissonReactive.java +++ b/redisson/src/main/java/org/redisson/RedissonReactive.java @@ -1142,6 +1142,7 @@ public final 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 b8de7727b..d947616b7 100644 --- a/redisson/src/main/java/org/redisson/RedissonRx.java +++ b/redisson/src/main/java/org/redisson/RedissonRx.java @@ -1119,6 +1119,7 @@ public final 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 2c91a3132..5cdad7f0c 100644 --- a/redisson/src/main/java/org/redisson/cache/LocalCacheListener.java +++ b/redisson/src/main/java/org/redisson/cache/LocalCacheListener.java @@ -298,6 +298,9 @@ public abstract class LocalCacheListener { loadAfterReconnection(); } + if (options.getReconnectionStrategy() == ReconnectionStrategy.RELOAD) { + reloadCache(); + } } public void notifyUpdate(CacheValue value) { @@ -358,6 +361,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");