Skip to content

Commit 0f03598

Browse files
committed
DATAREDIS-468 - Polishing.
Add DecoratedRedisConnection interface to unwrap decorated connections. When running on Redis Cluster, use keys/del instead of lua script because cluster connections do not support lua script execution. Original pull request: spring-projects#173.
1 parent 7024ef3 commit 0f03598

File tree

3 files changed

+67
-6
lines changed

3 files changed

+67
-6
lines changed

src/main/java/org/springframework/data/redis/cache/RedisCache.java

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.springframework.cache.support.SimpleValueWrapper;
2929
import org.springframework.dao.DataAccessException;
3030
import org.springframework.data.redis.RedisSystemException;
31+
import org.springframework.data.redis.connection.DecoratedRedisConnection;
3132
import org.springframework.data.redis.connection.RedisClusterConnection;
3233
import org.springframework.data.redis.connection.RedisConnection;
3334
import org.springframework.data.redis.connection.ReturnType;
@@ -39,10 +40,11 @@
3940

4041
/**
4142
* Cache implementation on top of Redis.
42-
*
43+
*
4344
* @author Costin Leau
4445
* @author Christoph Strobl
4546
* @author Thomas Darimont
47+
* @author Mark Paluch
4648
*/
4749
@SuppressWarnings("unchecked")
4850
public class RedisCache implements Cache {
@@ -54,7 +56,7 @@ public class RedisCache implements Cache {
5456

5557
/**
5658
* Constructs a new <code>RedisCache</code> instance.
57-
*
59+
*
5860
* @param name cache name
5961
* @param prefix
6062
* @param redisOperations
@@ -624,7 +626,16 @@ public Void doInLock(RedisConnection connection) throws DataAccessException {
624626
byte[] prefixToUse = Arrays.copyOf(metadata.getKeyPrefix(), metadata.getKeyPrefix().length + WILD_CARD.length);
625627
System.arraycopy(WILD_CARD, 0, prefixToUse, metadata.getKeyPrefix().length, WILD_CARD.length);
626628

627-
connection.eval(REMOVE_KEYS_BY_PATTERN_LUA, ReturnType.INTEGER, 0, prefixToUse);
629+
if(isClusterConnection(connection)) {
630+
631+
// load keys to the client because currently Redis Cluster connections do not allow eval of lua scripts.
632+
Set<byte[]> keys = connection.keys(prefixToUse);
633+
if (!keys.isEmpty()) {
634+
connection.del(keys.toArray(new byte[keys.size()][]));
635+
}
636+
} else {
637+
connection.eval(REMOVE_KEYS_BY_PATTERN_LUA, ReturnType.INTEGER, 0, prefixToUse);
638+
}
628639

629640
return null;
630641
}
@@ -765,8 +776,9 @@ public byte[] doInRedis(BinaryRedisCacheElement element, RedisConnection connect
765776

766777
return value;
767778
} catch (RuntimeException e) {
768-
769-
connection.discard();
779+
if (!isClusterConnection(connection)) {
780+
connection.discard();
781+
}
770782
throw e;
771783
}
772784
} finally {
@@ -810,6 +822,11 @@ public RuntimeException create(Object key, Callable<?> valueLoader, Throwable ca
810822
}
811823

812824
private static boolean isClusterConnection(RedisConnection connection) {
825+
826+
while (connection instanceof DecoratedRedisConnection) {
827+
connection = ((DecoratedRedisConnection) connection).getDelegate();
828+
}
829+
813830
return connection instanceof RedisClusterConnection;
814831
}
815832

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.data.redis.connection;
18+
19+
/**
20+
* Specifies that the connection decorates another {@link RedisConnection}.
21+
*
22+
* @author Mark Paluch
23+
* @since 1.7
24+
*/
25+
public interface DecoratedRedisConnection {
26+
27+
/**
28+
* Gets the underlying {@link RedisConnection}.
29+
*
30+
* @return never {@literal null}.
31+
*/
32+
RedisConnection getDelegate();
33+
34+
}

src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@
4949
* @author Jennifer Hickey
5050
* @author Christoph Strobl
5151
* @author Thomas Darimont
52+
* @author Mark Paluch
5253
*/
53-
public class DefaultStringRedisConnection implements StringRedisConnection {
54+
public class DefaultStringRedisConnection implements StringRedisConnection, DecoratedRedisConnection {
5455

5556
private static final byte[][] EMPTY_2D_BYTE_ARRAY = new byte[0][];
5657

@@ -2724,4 +2725,13 @@ public void migrate(byte[] key, RedisNode target, int dbIndex, MigrateOption opt
27242725
delegate.migrate(key, target, dbIndex, option, timeout);
27252726
}
27262727

2728+
/*
2729+
* (non-Javadoc)
2730+
* @see org.springframework.data.redis.connection.DecoratedRedisConnection#getDelegate()
2731+
*/
2732+
@Override
2733+
public RedisConnection getDelegate() {
2734+
return delegate;
2735+
}
2736+
27272737
}

0 commit comments

Comments
 (0)