Skip to content

Commit 435ace8

Browse files
christophstroblmp911de
authored andcommitted
DATAREDIS-719 - Rework FutureResult and implementations for Jedis/Lettuce.
We now encapsulate deferred results for pipelining and transactions entirely within FutureResult and its subtypes. FutureResult accepts a Supplier<T> for default values, if operations return null and reports whether its result requires conversion. JedisResult and LettuceResult are now top-level classes and no longer inner classes of their connection factories. Original pull request: #289.
1 parent 6ea78c7 commit 435ace8

31 files changed

+789
-413
lines changed

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

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,17 @@
1515
*/
1616
package org.springframework.data.redis.connection;
1717

18-
import java.util.*;
18+
import java.util.ArrayList;
19+
import java.util.Collection;
20+
import java.util.HashMap;
21+
import java.util.LinkedHashMap;
22+
import java.util.LinkedList;
23+
import java.util.List;
24+
import java.util.Map;
1925
import java.util.Map.Entry;
26+
import java.util.Properties;
27+
import java.util.Queue;
28+
import java.util.Set;
2029
import java.util.concurrent.TimeUnit;
2130

2231
import org.apache.commons.logging.Log;
@@ -725,7 +734,7 @@ public List<byte[]> mGet(byte[]... keys) {
725734
*/
726735
@Override
727736
public Boolean mSet(Map<byte[], byte[]> tuple) {
728-
return delegate.mSet(tuple);
737+
return convertAndReturn(delegate.mSet(tuple), identityConverter);
729738
}
730739

731740
/*
@@ -923,7 +932,7 @@ public void select(int dbIndex) {
923932
*/
924933
@Override
925934
public Boolean set(byte[] key, byte[] value) {
926-
return delegate.set(key, value);
935+
return convertAndReturn(delegate.set(key, value), identityConverter);
927936
}
928937

929938
/*
@@ -932,7 +941,7 @@ public Boolean set(byte[] key, byte[] value) {
932941
*/
933942
@Override
934943
public Boolean set(byte[] key, byte[] value, Expiration expiration, SetOption option) {
935-
return delegate.set(key, value, expiration, option);
944+
return convertAndReturn(delegate.set(key, value, expiration, option), identityConverter);
936945
}
937946

938947
/*
@@ -959,7 +968,7 @@ public void setConfig(String param, String value) {
959968
*/
960969
@Override
961970
public Boolean setEx(byte[] key, long seconds, byte[] value) {
962-
return delegate.setEx(key, seconds, value);
971+
return convertAndReturn(delegate.setEx(key, seconds, value), identityConverter);
963972
}
964973

965974
/*
@@ -968,7 +977,7 @@ public Boolean setEx(byte[] key, long seconds, byte[] value) {
968977
*/
969978
@Override
970979
public Boolean pSetEx(byte[] key, long milliseconds, byte[] value) {
971-
return delegate.pSetEx(key, milliseconds, value);
980+
return convertAndReturn(delegate.pSetEx(key, milliseconds, value), identityConverter);
972981
}
973982

974983
/*
@@ -2106,7 +2115,7 @@ public Boolean mSetNXString(Map<String, String> tuple) {
21062115
*/
21072116
@Override
21082117
public Boolean mSetString(Map<String, String> tuple) {
2109-
return delegate.mSet(serialize(tuple));
2118+
return mSet(serialize(tuple));
21102119
}
21112120

21122121
/*
@@ -2241,7 +2250,7 @@ public Long sDiffStore(String destKey, String... keys) {
22412250
*/
22422251
@Override
22432252
public Boolean set(String key, String value) {
2244-
return delegate.set(serialize(key), serialize(value));
2253+
return set(serialize(key), serialize(value));
22452254
}
22462255

22472256
/*
@@ -2268,7 +2277,7 @@ public Boolean setBit(String key, long offset, boolean value) {
22682277
*/
22692278
@Override
22702279
public Boolean setEx(String key, long seconds, String value) {
2271-
return delegate.setEx(serialize(key), seconds, serialize(value));
2280+
return setEx(serialize(key), seconds, serialize(value));
22722281
}
22732282

22742283
/*
@@ -3441,7 +3450,7 @@ public Set<byte[]> zRangeByLex(byte[] key, Range range, Limit limit) {
34413450
*/
34423451
@Override
34433452
public Set<String> zRangeByLex(String key) {
3444-
return this.zRangeByLex(key, Range.unbounded());
3453+
return zRangeByLex(key, Range.unbounded());
34453454
}
34463455

34473456
/*
@@ -3450,7 +3459,7 @@ public Set<String> zRangeByLex(String key) {
34503459
*/
34513460
@Override
34523461
public Set<String> zRangeByLex(String key, Range range) {
3453-
return this.zRangeByLex(key, range, null);
3462+
return zRangeByLex(key, range, null);
34543463
}
34553464

34563465
/*

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

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package org.springframework.data.redis.connection;
1717

18+
import java.util.function.Supplier;
19+
1820
import org.springframework.core.convert.converter.Converter;
1921
import org.springframework.lang.Nullable;
2022

@@ -28,23 +30,60 @@
2830
*/
2931
public abstract class FutureResult<T> {
3032

31-
protected T resultHolder;
33+
private T resultHolder;
34+
private final Supplier<?> defaultConversionResult;
3235

33-
protected boolean status = false;
36+
private boolean status = false;
3437

3538
@SuppressWarnings("rawtypes") //
3639
protected @Nullable Converter converter;
3740

41+
/**
42+
* Create new {@link FutureResult} for given object actually holding the result itself.
43+
*
44+
* @param resultHolder must not be {@literal null}.
45+
*/
3846
public FutureResult(T resultHolder) {
39-
this.resultHolder = resultHolder;
47+
this(resultHolder, val -> val);
4048
}
4149

50+
/**
51+
* Create new {@link FutureResult} for given object actually holding the result itself and a converter capable of
52+
* transforming the result via {@link #convert(Object)}.
53+
*
54+
* @param resultHolder must not be {@literal null}.
55+
* @param converter can be {@literal null} and will be defaulted to an identity converter {@code value -> value} to
56+
* preserve the original value.
57+
*/
58+
@SuppressWarnings("rawtypes")
59+
public FutureResult(T resultHolder, @Nullable Converter converter) {
60+
this(resultHolder, converter, () -> null);
61+
}
62+
63+
/**
64+
* Create new {@link FutureResult} for given object actually holding the result itself and a converter capable of
65+
* transforming the result via {@link #convert(Object)}.
66+
*
67+
* @param resultHolder must not be {@literal null}.
68+
* @param converter can be {@literal null} and will be defaulted to an identity converter {@code value -> value} to
69+
* preserve the original value.
70+
* @param defaultConversionResult must not be {@literal null}.
71+
* @since 2.1
72+
*/
4273
@SuppressWarnings("rawtypes")
43-
public FutureResult(T resultHolder, Converter converter) {
74+
public FutureResult(T resultHolder, @Nullable Converter converter, Supplier<?> defaultConversionResult) {
75+
4476
this.resultHolder = resultHolder;
45-
this.converter = converter;
77+
this.converter = converter != null ? converter : val -> val;
78+
this.defaultConversionResult = defaultConversionResult;
4679
}
4780

81+
/**
82+
* Get the object holding the actual result.
83+
*
84+
* @return never {@literal null}.
85+
* @since 1.1
86+
*/
4887
public T getResultHolder() {
4988
return resultHolder;
5089
}
@@ -60,14 +99,18 @@ public T getResultHolder() {
6099
public Object convert(@Nullable Object result) {
61100

62101
if (result == null) {
63-
return null;
102+
return computeDefaultResult(result);
64103
}
65104

66-
return (converter != null) ? converter.convert(result) : result;
105+
return computeDefaultResult(converter.convert(result));
67106
}
68107

69-
@SuppressWarnings("rawtypes")
70108
@Nullable
109+
private Object computeDefaultResult(@Nullable Object source) {
110+
return source != null ? source : defaultConversionResult.get();
111+
}
112+
113+
@SuppressWarnings("rawtypes")
71114
public Converter getConverter() {
72115
return converter;
73116
}
@@ -93,4 +136,12 @@ public void setStatus(boolean status) {
93136
*/
94137
@Nullable
95138
public abstract Object get();
139+
140+
/**
141+
* Indicate whether or not the actual result needs to be {@link #convert(Object) converted} before handing over.
142+
*
143+
* @return
144+
* @since 2.1
145+
*/
146+
public abstract boolean seeksConversion();
96147
}

src/main/java/org/springframework/data/redis/connection/convert/TransactionResultConverter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public List<Object> convert(List<Object> execResults) {
7171
: new RedisSystemException("Error reading future result.", source);
7272
}
7373
if (!(futureResult.isStatus())) {
74-
convertedResults.add(futureResult.convert(result));
74+
convertedResults.add(futureResult.seeksConversion() ? futureResult.convert(result) : result);
7575
}
7676
}
7777

0 commit comments

Comments
 (0)