Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit aa8c5a5

Browse files
Koooooo-7mp911de
authored andcommitted
Add TtlFunction to RedisCacheConfiguration for dynamic Time to Live.
We now support a TtlFunction to compute the time to live for cache entries. Closes #1433 Original pull request: #2587
1 parent 050beeb commit aa8c5a5

File tree

3 files changed

+62
-15
lines changed

3 files changed

+62
-15
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ public void put(Object key, @Nullable Object value) {
185185
}
186186

187187
getCacheWriter().put(getName(), createAndConvertCacheKey(key), serializeCacheValue(cacheValue),
188-
getCacheConfiguration().getTtl());
188+
getCacheConfiguration().getTtl(key, value));
189189
}
190190

191191
@Override
@@ -198,7 +198,7 @@ public ValueWrapper putIfAbsent(Object key, @Nullable Object value) {
198198
}
199199

200200
byte[] result = getCacheWriter().putIfAbsent(getName(), createAndConvertCacheKey(key),
201-
serializeCacheValue(cacheValue), getCacheConfiguration().getTtl());
201+
serializeCacheValue(cacheValue), getCacheConfiguration().getTtl(key, value));
202202

203203
return result != null ? new SimpleValueWrapper(fromStoreValue(deserializeCacheValue(result))) : null;
204204
}

‎src/main/java/org/springframework/data/redis/cache/RedisCacheConfiguration.java‎

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.nio.charset.StandardCharsets;
1919
import java.time.Duration;
20+
import java.util.function.BiFunction;
2021
import java.util.function.Consumer;
2122

2223
import org.springframework.cache.Cache;
@@ -40,6 +41,7 @@
4041
* @author Christoph Strobl
4142
* @author Mark Paluch
4243
* @author John Blum
44+
* @author Koy Zhuang
4345
* @since 2.0
4446
*/
4547
public class RedisCacheConfiguration {
@@ -106,7 +108,7 @@ public static RedisCacheConfiguration defaultCacheConfig(@Nullable ClassLoader c
106108

107109
registerDefaultConverters(conversionService);
108110

109-
return new RedisCacheConfiguration(Duration.ZERO, DEFAULT_CACHE_NULL_VALUES, DEFAULT_USE_PREFIX,
111+
return new RedisCacheConfiguration((k, v) -> Duration.ZERO, DEFAULT_CACHE_NULL_VALUES, DEFAULT_USE_PREFIX,
110112
CacheKeyPrefix.simple(),
111113
SerializationPair.fromSerializer(RedisSerializer.string()),
112114
SerializationPair.fromSerializer(RedisSerializer.java(classLoader)), conversionService);
@@ -119,17 +121,17 @@ public static RedisCacheConfiguration defaultCacheConfig(@Nullable ClassLoader c
119121

120122
private final ConversionService conversionService;
121123

122-
private final Durationttl;
124+
private final BiFunction<Object, Object, Duration> ttlProvider;
123125

124126
private final SerializationPair<String> keySerializationPair;
125127
private final SerializationPair<Object> valueSerializationPair;
126128

127129
@SuppressWarnings("unchecked")
128-
private RedisCacheConfiguration(Durationttl, Boolean cacheNullValues, Boolean usePrefix, CacheKeyPrefix keyPrefix,
130+
private RedisCacheConfiguration(BiFunction<Object, Object, Duration> ttlProvider, Boolean cacheNullValues, Boolean usePrefix, CacheKeyPrefix keyPrefix,
129131
SerializationPair<String> keySerializationPair, SerializationPair<?> valueSerializationPair,
130132
ConversionService conversionService) {
131133

132-
this.ttl = ttl;
134+
this.ttlProvider = ttlProvider;
133135
this.cacheNullValues = cacheNullValues;
134136
this.usePrefix = usePrefix;
135137
this.keyPrefix = keyPrefix;
@@ -165,7 +167,7 @@ public RedisCacheConfiguration computePrefixWith(CacheKeyPrefix cacheKeyPrefix)
165167

166168
Assert.notNull(cacheKeyPrefix, "Function for computing prefix must not be null");
167169

168-
return new RedisCacheConfiguration(ttl, cacheNullValues, DEFAULT_USE_PREFIX, cacheKeyPrefix,
170+
return new RedisCacheConfiguration(ttlProvider, cacheNullValues, DEFAULT_USE_PREFIX, cacheKeyPrefix,
169171
keySerializationPair, valueSerializationPair, conversionService);
170172
}
171173

@@ -178,7 +180,7 @@ public RedisCacheConfiguration computePrefixWith(CacheKeyPrefix cacheKeyPrefix)
178180
* @return new {@link RedisCacheConfiguration}.
179181
*/
180182
public RedisCacheConfiguration disableCachingNullValues() {
181-
return new RedisCacheConfiguration(ttl, DO_NOT_CACHE_NULL_VALUES, usePrefix, keyPrefix, keySerializationPair,
183+
return new RedisCacheConfiguration(ttlProvider, DO_NOT_CACHE_NULL_VALUES, usePrefix, keyPrefix, keySerializationPair,
182184
valueSerializationPair, conversionService);
183185
}
184186

@@ -191,12 +193,12 @@ public RedisCacheConfiguration disableCachingNullValues() {
191193
*/
192194
public RedisCacheConfiguration disableKeyPrefix() {
193195

194-
return new RedisCacheConfiguration(ttl, cacheNullValues, DO_NOT_USE_PREFIX, keyPrefix, keySerializationPair,
196+
return new RedisCacheConfiguration(ttlProvider, cacheNullValues, DO_NOT_USE_PREFIX, keyPrefix, keySerializationPair,
195197
valueSerializationPair, conversionService);
196198
}
197199

198200
/**
199-
* Set the ttl to apply for cache entries. Use {@link Duration#ZERO} to declare an eternal cache.
201+
* Set the constant ttl to apply for cache entries. Use {@link Duration#ZERO} to declare an eternal cache.
200202
*
201203
* @param ttl must not be {@literal null}.
202204
* @return new {@link RedisCacheConfiguration}.
@@ -205,10 +207,25 @@ public RedisCacheConfiguration entryTtl(Duration ttl) {
205207

206208
Assert.notNull(ttl, "TTL duration must not be null");
207209

208-
return new RedisCacheConfiguration(ttl, cacheNullValues, usePrefix, keyPrefix, keySerializationPair,
210+
return new RedisCacheConfiguration((k, v) -> ttl, cacheNullValues, usePrefix, keyPrefix, keySerializationPair,
209211
valueSerializationPair, conversionService);
210212
}
211213

214+
/**
215+
* Set the ttl Provider, which can dynamic provide ttl to apply for cache entries.
216+
* @param ttlProvider {@link BiFunction} calculate ttl with the actual original cache key and value,
217+
* which must not be {@literal null}, and the ttl must not be {@literal null} either.
218+
*
219+
* @return new {@link RedisCacheConfiguration}.
220+
*/
221+
public RedisCacheConfiguration entryTtlProvider(BiFunction<Object, Object, Duration> ttlProvider) {
222+
223+
Assert.notNull(ttlProvider, "ttlProvider must not be null");
224+
225+
return new RedisCacheConfiguration(ttlProvider, cacheNullValues, usePrefix, keyPrefix, keySerializationPair,
226+
valueSerializationPair, conversionService);
227+
}
228+
212229
/**
213230
* Define the {@link SerializationPair} used for de-/serializing cache keys.
214231
*
@@ -219,7 +236,7 @@ public RedisCacheConfiguration serializeKeysWith(SerializationPair<String> keySe
219236

220237
Assert.notNull(keySerializationPair, "KeySerializationPair must not be null");
221238

222-
return new RedisCacheConfiguration(ttl, cacheNullValues, usePrefix, keyPrefix, keySerializationPair,
239+
return new RedisCacheConfiguration(ttlProvider, cacheNullValues, usePrefix, keyPrefix, keySerializationPair,
223240
valueSerializationPair, conversionService);
224241
}
225242

@@ -233,7 +250,7 @@ public RedisCacheConfiguration serializeValuesWith(SerializationPair<?> valueSer
233250

234251
Assert.notNull(valueSerializationPair, "ValueSerializationPair must not be null");
235252

236-
return new RedisCacheConfiguration(ttl, cacheNullValues, usePrefix, keyPrefix, keySerializationPair,
253+
return new RedisCacheConfiguration(ttlProvider, cacheNullValues, usePrefix, keyPrefix, keySerializationPair,
237254
valueSerializationPair, conversionService);
238255
}
239256

@@ -247,7 +264,7 @@ public RedisCacheConfiguration withConversionService(ConversionService conversio
247264

248265
Assert.notNull(conversionService, "ConversionService must not be null");
249266

250-
return new RedisCacheConfiguration(ttl, cacheNullValues, usePrefix, keyPrefix, keySerializationPair,
267+
return new RedisCacheConfiguration(ttlProvider, cacheNullValues, usePrefix, keyPrefix, keySerializationPair,
251268
valueSerializationPair, conversionService);
252269
}
253270

@@ -301,9 +318,21 @@ public SerializationPair<Object> getValueSerializationPair() {
301318
}
302319

303320
/**
304-
* @return The expiration time (ttl) for cache entries. Never {@literal null}.
321+
* @return The constant expiration time (ttl) for cache entries. Never {@literal null}.
305322
*/
306323
public Duration getTtl() {
324+
Duration ttl = ttlProvider.apply(Object.class, Object.class);
325+
Assert.notNull(ttl, "TTL duration must not be null");
326+
return ttl;
327+
}
328+
329+
/**
330+
* @return The expiration time (ttl) for cache entries with original key and value. Never {@literal null}.
331+
*/
332+
public Duration getTtl(Object key, Object val) {
333+
Duration ttl = ttlProvider.apply(key, val);
334+
Assert.notNull(ttl, "TTL duration must not be null");
335+
307336
return ttl;
308337
}
309338

‎src/test/java/org/springframework/data/redis/cache/RedisCacheConfigurationUnitTests.java‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
import org.springframework.instrument.classloading.ShadowingClassLoader;
2525
import org.springframework.lang.Nullable;
2626

27+
import java.time.Duration;
28+
import java.util.function.BiFunction;
29+
2730
/**
2831
* Unit tests for {@link RedisCacheConfiguration}.
2932
*
@@ -56,6 +59,21 @@ void shouldAllowConverterRegistration() {
5659
assertThat(config.getConversionService().canConvert(DomainType.class, String.class)).isTrue();
5760
}
5861

62+
63+
@Test
64+
void shouldGetDynamicTtlGivenTtlProvider() {
65+
66+
BiFunction<Object, Object, Duration> ttlProvider = (key, val) ->
67+
Duration.ofSeconds(Integer.parseInt(key + String.valueOf(val)));
68+
69+
RedisCacheConfiguration defaultCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
70+
.entryTtlProvider(ttlProvider);
71+
72+
assertThat(defaultCacheConfiguration.getTtl(1, 12)).isEqualTo(Duration.ofSeconds(112));
73+
assertThat(defaultCacheConfiguration.getTtl(15, 22)).isEqualTo(Duration.ofSeconds(1522));
74+
assertThat(defaultCacheConfiguration.getTtl(77, 0)).isEqualTo(Duration.ofSeconds(770));
75+
}
76+
5977
private static class DomainType {
6078

6179
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /