INT-4507: Use UNLINK in RedisMessageStore if any

JIRA: https://jira.spring.io/browse/INT-4507

* Add `RedisUtils` with the `isUnlinkAvailable()` to check the Redis
server version to be sure that `UNLINK` is available or not
* Use `RedisUtils.isUnlinkAvailable()` in the `RedisMessageStore` and
`RedisLockRegistry` when a removal functionality is performed
* Add `AbstractKeyValueMessageStore.doRemoveAll(Collection<Object> ids)`
for optimization
* Implement `doRemoveAll()` in the `RedisMessageStore` and
`GemfireMessageStore`

**Cherry-pick to 5.0.x**
This commit is contained in:
Artem Bilan
2018-07-25 14:04:18 -04:00
committed by Gary Russell
parent d61cd790fe
commit 88c7646ed9
6 changed files with 137 additions and 20 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,8 +20,10 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.messaging.Message;
@@ -243,11 +245,21 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
if (mgm != null) {
Assert.isInstanceOf(MessageGroupMetadata.class, mgm);
MessageGroupMetadata messageGroupMetadata = (MessageGroupMetadata) mgm;
for (Message<?> messageToRemove : messages) {
UUID messageId = messageToRemove.getHeaders().getId();
messageGroupMetadata.remove(messageId);
doRemove(this.messagePrefix + messageId);
}
List<UUID> ids =
messages.stream()
.map(messageToRemove -> messageToRemove.getHeaders().getId())
.collect(Collectors.toList());
messageGroupMetadata.removeAll(ids);
List<Object> messageIds =
ids.stream()
.map(id -> this.messagePrefix + id)
.collect(Collectors.toList());
doRemoveAll(messageIds);
messageGroupMetadata.setLastModified(System.currentTimeMillis());
doStore(this.groupPrefix + groupId, messageGroupMetadata);
}
@@ -275,10 +287,13 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
Assert.isInstanceOf(MessageGroupMetadata.class, mgm);
MessageGroupMetadata messageGroupMetadata = (MessageGroupMetadata) mgm;
Iterator<UUID> messageIds = messageGroupMetadata.messageIdIterator();
while (messageIds.hasNext()) {
removeMessage(messageIds.next());
}
List<Object> messageIds =
messageGroupMetadata.getMessageIds()
.stream()
.map(id -> this.messagePrefix + id)
.collect(Collectors.toList());
doRemoveAll(messageIds);
}
}
@@ -325,7 +340,7 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
@Override
public Collection<Message<?>> getMessagesForGroup(Object groupId) {
MessageGroupMetadata groupMetadata = getGroupMetadata(groupId);
ArrayList<Message<?>> messages = new ArrayList<Message<?>>();
ArrayList<Message<?>> messages = new ArrayList<>();
if (groupMetadata != null) {
Iterator<UUID> messageIds = groupMetadata.messageIdIterator();
while (messageIds.hasNext()) {
@@ -345,7 +360,7 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
}
private Collection<String> normalizeKeys(Collection<String> keys) {
Set<String> normalizedKeys = new HashSet<String>();
Set<String> normalizedKeys = new HashSet<>();
for (Object key : keys) {
String strKey = (String) key;
if (strKey.startsWith(this.groupPrefix)) {
@@ -378,6 +393,8 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
protected abstract Object doRemove(Object id);
protected abstract void doRemoveAll(Collection<Object> ids);
protected abstract Collection<?> doListKeys(String keyPattern);
private final class MessageGroupIterator implements Iterator<MessageGroup> {

View File

@@ -17,6 +17,7 @@
package org.springframework.integration.store;
import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -39,7 +40,7 @@ public class MessageGroupMetadata implements Serializable {
private static final long serialVersionUID = 1L;
private List<UUID> messageIds = new LinkedList<UUID>();
private List<UUID> messageIds = new LinkedList<>();
private long timestamp;
@@ -68,6 +69,10 @@ public class MessageGroupMetadata implements Serializable {
this.messageIds.remove(messageId);
}
public void removeAll(Collection<UUID> messageIds) {
this.messageIds.removeAll(messageIds);
}
boolean add(UUID messageId) {
return !this.messageIds.contains(messageId) && this.messageIds.add(messageId);
}