DATAREDIS-589 - Move secondary index cleanup to MappingExpirationListener.
We now no longer rely on ApplicationEvents captured in the RedisKeyValueAdapter for performing cleanup operations for expired keys, but do this along with the phantom key removal. This removes a flaw when initializing a non repository related KeyspaceEventListener publishing events that actually are unrelated to the Adapter. Additionally upgraded test infrastructure to utilize Redis 3.2.6 with disabled protected-mode and enabled keyspace-events. Original pull request: #232.
This commit is contained in:
committed by
Mark Paluch
parent
253c281205
commit
639b1e2b55
@@ -48,12 +48,24 @@ public class RedisKeyExpiredEvent<T> extends RedisKeyspaceEvent {
|
||||
|
||||
/**
|
||||
* Creates new {@link RedisKeyExpiredEvent}
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public RedisKeyExpiredEvent(byte[] key, Object value) {
|
||||
super(key);
|
||||
this(null, key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link RedisKeyExpiredEvent}
|
||||
*
|
||||
* @pamam channel
|
||||
* @param key
|
||||
* @param value
|
||||
* @since 1.8
|
||||
*/
|
||||
public RedisKeyExpiredEvent(String channel, byte[] key, Object value) {
|
||||
super(channel, key);
|
||||
|
||||
args = ByteUtils.split(key, ':');
|
||||
this.value = value;
|
||||
|
||||
@@ -64,6 +64,7 @@ import org.springframework.data.redis.util.ByteUtils;
|
||||
import org.springframework.data.util.CloseableIterator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Redis specific {@link KeyValueAdapter} implementation. Uses binary codec to read/write data from/to Redis. Objects
|
||||
@@ -367,7 +368,6 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
|
||||
List<byte[]> keys = new ArrayList<byte[]>(ids);
|
||||
|
||||
|
||||
if (keys.isEmpty() || keys.size() < offset) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -701,28 +701,7 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
*/
|
||||
@Override
|
||||
public void onApplicationEvent(RedisKeyspaceEvent event) {
|
||||
|
||||
LOGGER.debug("Received %s .", event);
|
||||
|
||||
if (event instanceof RedisKeyExpiredEvent) {
|
||||
|
||||
final RedisKeyExpiredEvent expiredEvent = (RedisKeyExpiredEvent) event;
|
||||
|
||||
redisOps.execute(new RedisCallback<Void>() {
|
||||
|
||||
@Override
|
||||
public Void doInRedis(RedisConnection connection) throws DataAccessException {
|
||||
|
||||
LOGGER.debug("Cleaning up expired key '%s' data structures in keyspace '%s'.", expiredEvent.getSource(),
|
||||
expiredEvent.getKeyspace());
|
||||
|
||||
connection.sRem(toBytes(expiredEvent.getKeyspace()), expiredEvent.getId());
|
||||
new IndexWriter(connection, converter).removeKeyFromIndexes(expiredEvent.getKeyspace(), expiredEvent.getId());
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
// just a customization hook
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -814,12 +793,29 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
if (!org.springframework.util.CollectionUtils.isEmpty(hash)) {
|
||||
connection.del(phantomKey);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
});
|
||||
|
||||
Object value = converter.read(Object.class, new RedisData(hash));
|
||||
publishEvent(new RedisKeyExpiredEvent(key, value));
|
||||
|
||||
String channel = !ObjectUtils.isEmpty(message.getChannel())
|
||||
? converter.getConversionService().convert(message.getChannel(), String.class) : null;
|
||||
|
||||
final RedisKeyExpiredEvent event = new RedisKeyExpiredEvent(channel, key, value);
|
||||
|
||||
ops.execute(new RedisCallback<Void>() {
|
||||
@Override
|
||||
public Void doInRedis(RedisConnection connection) throws DataAccessException {
|
||||
|
||||
connection.sRem(converter.getConversionService().convert(event.getKeyspace(), byte[].class), event.getId());
|
||||
new IndexWriter(connection, converter).removeKeyFromIndexes(event.getKeyspace(), event.getId());
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
publishEvent(event);
|
||||
}
|
||||
|
||||
private boolean isKeyExpirationMessage(Message message) {
|
||||
|
||||
@@ -25,13 +25,28 @@ import org.springframework.context.ApplicationEvent;
|
||||
*/
|
||||
public class RedisKeyspaceEvent extends ApplicationEvent {
|
||||
|
||||
private final String channel;
|
||||
|
||||
/**
|
||||
* Creates new {@link RedisKeyspaceEvent}.
|
||||
*
|
||||
*
|
||||
* @param key The key that expired. Must not be {@literal null}.
|
||||
*/
|
||||
public RedisKeyspaceEvent(byte[] key) {
|
||||
this(null, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link RedisKeyspaceEvent}.
|
||||
*
|
||||
* @param channel The source channel aka subscription topic. Can be {@literal null}.
|
||||
* @param key The key that expired. Must not be {@literal null}.
|
||||
* @since 1.8
|
||||
*/
|
||||
public RedisKeyspaceEvent(String channel, byte[] key) {
|
||||
|
||||
super(key);
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -42,4 +57,13 @@ public class RedisKeyspaceEvent extends ApplicationEvent {
|
||||
return (byte[]) super.getSource();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return can be {@literal null}.
|
||||
* @since 1.8
|
||||
*/
|
||||
public String getChannel() {
|
||||
return this.channel;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user