From 1c4981749940372a0b363535bd4bb1ce6f8ac377 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Mon, 27 Jul 2020 09:24:13 +0300 Subject: [PATCH] Fixed - deserialization exception is thrown if RMapCache.EntryRemovedListener is set. #2941 --- .../java/org/redisson/RedissonMapCache.java | 33 ++++++++++++------- .../org/redisson/RedissonMapCacheTest.java | 31 ++++++++++++++--- 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/redisson/src/main/java/org/redisson/RedissonMapCache.java b/redisson/src/main/java/org/redisson/RedissonMapCache.java index b8a238b06..2ec956357 100644 --- a/redisson/src/main/java/org/redisson/RedissonMapCache.java +++ b/redisson/src/main/java/org/redisson/RedissonMapCache.java @@ -366,7 +366,8 @@ public class RedissonMapCache extends RedissonMap implements RMapCac " redis.call('zrem', lastAccessTimeSetName, lruItem); " + " if lruItemValue ~= false then " + " local removedChannelName = KEYS[6]; " + - " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(lruItemValue), lruItemValue); " + + "local ttl, obj = struct.unpack('dLc0', lruItemValue);" + + " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(obj), obj);" + " redis.call('publish', removedChannelName, msg); " + "end; " + " end; " + @@ -522,7 +523,8 @@ public class RedissonMapCache extends RedissonMap implements RMapCac " redis.call('zrem', lastAccessTimeSetName, lruItem);" + " if lruItemValue ~= false then " + " local removedChannelName = KEYS[7];" + - " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(lruItemValue), lruItemValue);" + + "local ttl, obj = struct.unpack('dLc0', lruItemValue);" + + " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(obj), obj);" + " redis.call('publish', removedChannelName, msg);" + "end; " + " end;" + @@ -593,7 +595,8 @@ public class RedissonMapCache extends RedissonMap implements RMapCac " redis.call('zrem', lastAccessTimeSetName, lruItem); " + " if lruItemValue ~= false then " + " local removedChannelName = KEYS[6]; " + - " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(lruItemValue), lruItemValue); " + + "local ttl, obj = struct.unpack('dLc0', lruItemValue);" + + " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(obj), obj);" + " redis.call('publish', removedChannelName, msg); " + "end; " + " end; " + @@ -691,7 +694,8 @@ public class RedissonMapCache extends RedissonMap implements RMapCac " redis.call('zrem', lastAccessTimeSetName, lruItem); " + " if lruItemValue ~= false then " + " local removedChannelName = KEYS[7]; " + - " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(lruItemValue), lruItemValue); " + + "local ttl, obj = struct.unpack('dLc0', lruItemValue);" + + " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(obj), obj);" + " redis.call('publish', removedChannelName, msg); " + "end; " + " end; " + @@ -819,7 +823,8 @@ public class RedissonMapCache extends RedissonMap implements RMapCac " redis.call('zrem', lastAccessTimeSetName, lruItem); " + " if lruItemValue ~= false then " + " local removedChannelName = KEYS[7]; " + - " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(lruItemValue), lruItemValue); " + + "local ttl, obj = struct.unpack('dLc0', lruItemValue);" + + " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(obj), obj);" + " redis.call('publish', removedChannelName, msg); " + "end; " + " end; " + @@ -954,7 +959,8 @@ public class RedissonMapCache extends RedissonMap implements RMapCac " redis.call('zrem', lastAccessTimeSetName, lruItem); " + " if lruItemValue ~= false then " + " local removedChannelName = KEYS[7]; " + - " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(lruItemValue), lruItemValue); " + + "local ttl, obj = struct.unpack('dLc0', lruItemValue);" + + " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(obj), obj);" + " redis.call('publish', removedChannelName, msg); " + "end; " + " end; " + @@ -1356,7 +1362,8 @@ public class RedissonMapCache extends RedissonMap implements RMapCac " redis.call('zrem', lastAccessTimeSetName, lruItem); " + " if lruItemValue ~= false then " + " local removedChannelName = KEYS[7]; " + - " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(lruItemValue), lruItemValue); " + + "local ttl, obj = struct.unpack('dLc0', lruItemValue);" + + " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(obj), obj);" + " redis.call('publish', removedChannelName, msg); " + "end; " + " end; " + @@ -1408,7 +1415,8 @@ public class RedissonMapCache extends RedissonMap implements RMapCac " redis.call('zrem', lastAccessTimeSetName, lruItem); " + " if lruItemValue ~= false then " + " local removedChannelName = KEYS[6]; " + - " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(lruItemValue), lruItemValue); " + + "local ttl, obj = struct.unpack('dLc0', lruItemValue);" + + " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(obj), obj);" + " redis.call('publish', removedChannelName, msg); " + "end; " + " end; " + @@ -1554,7 +1562,8 @@ public class RedissonMapCache extends RedissonMap implements RMapCac " redis.call('zrem', lastAccessTimeSetName, lruItem); " + " if lruItemValue ~= false then " + " local removedChannelName = KEYS[6]; " + - " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(lruItemValue), lruItemValue); " + + "local ttl, obj = struct.unpack('dLc0', lruItemValue);" + + " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(obj), obj);" + " redis.call('publish', removedChannelName, msg); " + "end; " + " end; " + @@ -1747,7 +1756,8 @@ public class RedissonMapCache extends RedissonMap implements RMapCac " redis.call('zrem', lastAccessTimeSetName, lruItem);" + " if lruItemValue ~= false then " + " local removedChannelName = KEYS[7];" + - " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(lruItemValue), lruItemValue);" + + "local ttl, obj = struct.unpack('dLc0', lruItemValue);" + + " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(obj), obj);" + " redis.call('publish', removedChannelName, msg);" + "end; " + " end;" + @@ -1846,7 +1856,8 @@ public class RedissonMapCache extends RedissonMap implements RMapCac " redis.call('zrem', lastAccessTimeSetName, lruItem);" + " if lruItemValue ~= false then " + " local removedChannelName = KEYS[7];" + - " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(lruItemValue), lruItemValue);" + + "local ttl, obj = struct.unpack('dLc0', lruItemValue);" + + " local msg = struct.pack('Lc0Lc0', string.len(lruItem), lruItem, string.len(obj), obj);" + " redis.call('publish', removedChannelName, msg);" + "end; " + " end;" + diff --git a/redisson/src/test/java/org/redisson/RedissonMapCacheTest.java b/redisson/src/test/java/org/redisson/RedissonMapCacheTest.java index dc74c5f56..d04ca24f2 100644 --- a/redisson/src/test/java/org/redisson/RedissonMapCacheTest.java +++ b/redisson/src/test/java/org/redisson/RedissonMapCacheTest.java @@ -16,16 +16,14 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; +import org.awaitility.Awaitility; import org.awaitility.Duration; import org.joor.Reflect; import org.junit.Assert; import org.junit.Assume; import org.junit.Test; -import org.redisson.api.MapOptions; +import org.redisson.api.*; import org.redisson.api.MapOptions.WriteMode; -import org.redisson.api.RMap; -import org.redisson.api.RMapCache; -import org.redisson.api.RedissonClient; import org.redisson.api.map.event.EntryCreatedListener; import org.redisson.api.map.event.EntryEvent; import org.redisson.api.map.event.EntryExpiredListener; @@ -42,6 +40,31 @@ import org.redisson.eviction.EvictionScheduler; public class RedissonMapCacheTest extends BaseMapTest { + @Test + public void testRemoveListener() { + RMapCache rMapCache = redisson.getMapCache("test", + LocalCachedMapOptions.defaults().evictionPolicy(LocalCachedMapOptions.EvictionPolicy.LRU) + .timeToLive(-1)); + rMapCache.trySetMaxSize(5); + AtomicBoolean removed = new AtomicBoolean(); + rMapCache.addListener(new EntryRemovedListener() { + @Override + public void onRemoved(EntryEvent event) { + removed.set(true); + } + }); + + rMapCache.put(1L, "1"); + rMapCache.put(2L, "2"); + rMapCache.put(3L, "3"); + rMapCache.put(4L, "4"); + rMapCache.put(5L, "5"); + + rMapCache.put(6L, "6"); + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilTrue(removed); + } + @Test public void testDestroy() { RMapCache cache = redisson.getMapCache("test");