Fixed - collection fields aren't deleted when RLiveObject expires or is deleted. #5103

pull/5139/head
Nikita Koksharov 2 years ago
parent 329de345f1
commit e0a510bf26

@ -33,6 +33,7 @@ import org.redisson.api.annotation.*;
import org.redisson.api.condition.Condition;
import org.redisson.client.codec.StringCodec;
import org.redisson.client.protocol.RedisCommand;
import org.redisson.client.protocol.RedisCommands;
import org.redisson.client.protocol.convertor.Convertor;
import org.redisson.client.protocol.decoder.ListMultiDecoder2;
import org.redisson.client.protocol.decoder.ListScanResult;
@ -65,7 +66,6 @@ public class RedissonLiveObjectService implements RLiveObjectService {
private final ConcurrentMap<Class<?>, Class<?>> classCache;
private final CommandAsyncExecutor commandExecutor;
private final LiveObjectSearch seachEngine;
private static final AtomicBoolean LISTENER_LATCH = new AtomicBoolean();
public RedissonLiveObjectService(ConcurrentMap<Class<?>, Class<?>> classCache,
CommandAsyncExecutor commandExecutor) {
@ -73,7 +73,7 @@ public class RedissonLiveObjectService implements RLiveObjectService {
this.commandExecutor = commandExecutor;
this.seachEngine = new LiveObjectSearch(commandExecutor);
if (LISTENER_LATCH.compareAndSet(false, true)) {
if (commandExecutor.getServiceManager().getLiveObjectLatch().compareAndSet(false, true)) {
RPatternTopic topic = new RedissonPatternTopic(StringCodec.INSTANCE, commandExecutor, "__keyevent@*:expired");
topic.addListenerAsync(String.class, (pattern, channel, msg) -> {
if (msg.contains("redisson_live_object:")) {
@ -617,6 +617,8 @@ public class RedissonLiveObjectService implements RLiveObjectService {
String mapName = namingScheme.getName(entityClass, id);
Object liveObjectId = namingScheme.resolveId(mapName);
deleteCollections(id, entityClass, ce);
RMap<String, Object> liveMap = new RedissonMap<>(namingScheme.getCodec(), commandExecutor,
mapName, null, null, null);
Map<String, ?> values = liveMap.getAll(fieldNames);
@ -642,6 +644,8 @@ public class RedissonLiveObjectService implements RLiveObjectService {
CommandBatchService ce = new CommandBatchService(commandExecutor);
FieldList<InDefinedShape> fields = Introspectior.getFieldsWithAnnotation(entityClass, RIndex.class);
deleteCollections(id, entityClass, ce);
NamingScheme namingScheme = commandExecutor.getObjectBuilder().getNamingScheme(entityClass);
String mapName = namingScheme.getName(entityClass, id);
Object liveObjectId = namingScheme.resolveId(mapName);
@ -661,6 +665,21 @@ public class RedissonLiveObjectService implements RLiveObjectService {
ce.execute();
}
private void deleteCollections(Object id, Class<?> entityClass, CommandBatchService ce) {
for (InDefinedShape field : Introspectior.getAllFields(entityClass)) {
try {
Field f = ClassUtils.getDeclaredField(entityClass, field.getName());
RObject rObject = commandExecutor.getObjectBuilder().createObject(id, entityClass, f.getType(), field.getName());
if (rObject != null) {
RedissonObject ro = (RedissonObject) rObject;
ce.writeAsync(ro.getRawName(), RedisCommands.DEL, ro.getRawName());
}
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
}
public RFuture<Long> delete(Object id, Class<?> entityClass, NamingScheme namingScheme, CommandBatchService ce) {
FieldList<InDefinedShape> fields = Introspectior.getFieldsWithAnnotation(entityClass, RIndex.class);
Set<String> fieldNames = fields.stream().map(f -> f.getName()).collect(Collectors.toSet());

@ -58,6 +58,7 @@ import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
@ -432,4 +433,9 @@ public class ServiceManager {
return id;
}
private final AtomicBoolean liveObjectLatch = new AtomicBoolean();
public AtomicBoolean getLiveObjectLatch() {
return liveObjectLatch;
}
}

@ -328,6 +328,8 @@ public class RedissonLiveObjectServiceTest extends BaseTest {
@RIndex
private int num2;
private List<Long> coll;
protected TestIndexed() {
}
@ -339,7 +341,15 @@ public class RedissonLiveObjectServiceTest extends BaseTest {
public String getId() {
return id;
}
public List<Long> getColl() {
return coll;
}
public void setColl(List<Long> coll) {
this.coll = coll;
}
public Boolean getBool1() {
return bool1;
}
@ -1716,11 +1726,11 @@ public class RedissonLiveObjectServiceTest extends BaseTest {
myObject = service.persist(myObject);
myObject.setName1("123345");
myObject.setNum1(455);
assertThat(redisson.getKeys().count()).isEqualTo(5);
myObject.setColl(Arrays.asList(1L, 2L));
assertThat(redisson.getKeys().count()).isEqualTo(6);
assertTrue(service.asLiveObject(myObject).isExists());
service.asRMap(myObject).expire(Duration.ofSeconds(1));
Thread.sleep(2000);
assertFalse(service.asLiveObject(myObject).isExists());
assertThat(redisson.getKeys().count()).isZero();
redisson.shutdown();

Loading…
Cancel
Save