From 4ad13b9cc87fa6a3c562d0c33072bc300eefa26b Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Mon, 27 Nov 2023 13:16:09 +0300 Subject: [PATCH] Fixed - RLiveObjectService.persist() method with varargs hangs in cluster mode. #5449 --- .../liveobject/core/AccessorInterceptor.java | 25 +++++++++++++------ .../RedissonLiveObjectServiceTest.java | 18 +++++++++++-- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/redisson/src/main/java/org/redisson/liveobject/core/AccessorInterceptor.java b/redisson/src/main/java/org/redisson/liveobject/core/AccessorInterceptor.java index 0fb283fdc..c84ce6ffd 100644 --- a/redisson/src/main/java/org/redisson/liveobject/core/AccessorInterceptor.java +++ b/redisson/src/main/java/org/redisson/liveobject/core/AccessorInterceptor.java @@ -38,6 +38,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.*; import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; import java.util.regex.Pattern; /** @@ -204,15 +205,23 @@ public class AccessorInterceptor { } else { if (ClassUtils.isAnnotationPresent(field.getType(), REntity.class) || commandExecutor.getConnectionManager().isClusterMode()) { - Object value = liveMap.remove(field.getName()); - if (value != null) { - RMultimapAsync map = new RedissonSetMultimap<>(namingScheme.getCodec(), ce, indexName); - Object k = value; - if (ClassUtils.isAnnotationPresent(field.getType(), REntity.class)) { - k = ((RLiveObject) value).getLiveObjectId(); - } - map.removeAsync(k, ((RLiveObject) me).getLiveObjectId()); + CompletableFuture f; + if (commandExecutor instanceof CommandBatchService) { + f = liveMap.removeAsync(field.getName()).toCompletableFuture(); + } else { + Object value = liveMap.remove(field.getName()); + f = CompletableFuture.completedFuture(value); } + f.thenAccept(value -> { + if (value != null) { + RMultimapAsync map = new RedissonSetMultimap<>(namingScheme.getCodec(), ce, indexName); + Object k = value; + if (ClassUtils.isAnnotationPresent(field.getType(), REntity.class)) { + k = ((RLiveObject) value).getLiveObjectId(); + } + map.removeAsync(k, ((RLiveObject) me).getLiveObjectId()); + } + }); } else { removeAsync(ce, indexName, ((RedissonObject) liveMap).getRawName(), namingScheme.getCodec(), ((RLiveObject) me).getLiveObjectId(), field.getName()); diff --git a/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java b/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java index 428a6bf50..13b18f0f6 100644 --- a/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java +++ b/redisson/src/test/java/org/redisson/RedissonLiveObjectServiceTest.java @@ -6,12 +6,10 @@ import org.junit.jupiter.api.Timeout; import org.redisson.api.*; import org.redisson.api.annotation.*; import org.redisson.api.condition.Conditions; -import org.redisson.config.Config; import org.redisson.liveobject.resolver.DefaultNamingScheme; import org.redisson.liveobject.resolver.LongGenerator; import org.redisson.liveobject.resolver.UUIDGenerator; -import java.io.IOException; import java.io.Serializable; import java.time.Duration; import java.util.*; @@ -23,6 +21,7 @@ import static org.junit.jupiter.api.Assertions.*; /** * * @author Rui Gu (https://github.com/jackygurui) + * @author Nikita Koksharov */ public class RedissonLiveObjectServiceTest extends RedisDockerTest { @@ -730,6 +729,21 @@ public class RedissonLiveObjectServiceTest extends RedisDockerTest { assertThat(ids3).isEqualTo(2); } + @Test + public void testPersistInCluster() { + testInCluster(redisson -> { + RLiveObjectService liveObjectService = redisson.getLiveObjectService(); + TestIndexed item1 = new TestIndexed("1"); + item1.setName1("name1"); + item1.setName2("name2"); + item1.setNum1(123); + + TestIndexed item2 = new TestIndexed("2"); + + liveObjectService.persist(item1, item2); + }); + } + @Test public void testIndexUpdateCluster() { testInCluster(redisson -> {