15
15
*/
16
16
package org .springframework .data .redis .cache ;
17
17
18
+ import reactor .core .publisher .Mono ;
19
+
20
+ import java .nio .ByteBuffer ;
18
21
import java .nio .charset .StandardCharsets ;
19
22
import java .time .Duration ;
20
23
import java .util .concurrent .TimeUnit ;
21
24
import java .util .function .Consumer ;
22
25
import java .util .function .Function ;
23
26
24
27
import org .springframework .dao .PessimisticLockingFailureException ;
28
+ import org .springframework .data .redis .connection .ReactiveRedisConnection ;
29
+ import org .springframework .data .redis .connection .ReactiveRedisConnectionFactory ;
25
30
import org .springframework .data .redis .connection .RedisConnection ;
26
31
import org .springframework .data .redis .connection .RedisConnectionFactory ;
27
32
import org .springframework .data .redis .connection .RedisStringCommands .SetOption ;
@@ -114,8 +119,8 @@ public byte[] get(String name, byte[] key, @Nullable Duration ttl) {
114
119
Assert .notNull (key , "Key must not be null" );
115
120
116
121
byte [] result = shouldExpireWithin (ttl )
117
- ? execute (name , connection -> connection .stringCommands ().getEx (key , Expiration .from (ttl )))
118
- : execute (name , connection -> connection .stringCommands ().get (key ));
122
+ ? execute (name , connection -> connection .stringCommands ().getEx (key , Expiration .from (ttl )))
123
+ : execute (name , connection -> connection .stringCommands ().get (key ));
119
124
120
125
statistics .incGets (name );
121
126
@@ -128,6 +133,32 @@ public byte[] get(String name, byte[] key, @Nullable Duration ttl) {
128
133
return result ;
129
134
}
130
135
136
+ @ Override
137
+ public Mono <ByteBuffer > retrieve (String name , byte [] key , @ Nullable Duration ttl ) {
138
+
139
+ assertReactiveRedisConnectionFactory ();
140
+
141
+ Assert .notNull (name , "Name must not be null" );
142
+ Assert .notNull (key , "Key must not be null" );
143
+
144
+ ByteBuffer wrappedKey = ByteBuffer .wrap (key );
145
+
146
+ Mono <ByteBuffer > result = shouldExpireWithin (ttl )
147
+ ? executeReactively (name , connection -> connection .stringCommands ().getEx (wrappedKey , Expiration .from (ttl )))
148
+ : executeReactively (name , connection -> connection .stringCommands ().get (wrappedKey ));
149
+
150
+ result = result .doOnSuccess (byteBuffer -> {
151
+ if (byteBuffer != null ) {
152
+ statistics .incHits (name );
153
+ }
154
+ else {
155
+ statistics .incMisses (name );
156
+ }
157
+ }).doFirst (() -> statistics .incGets (name ));
158
+
159
+ return result ;
160
+ }
161
+
131
162
@ Override
132
163
public void put (String name , byte [] key , byte [] value , @ Nullable Duration ttl ) {
133
164
@@ -308,6 +339,18 @@ private void executeLockFree(Consumer<RedisConnection> callback) {
308
339
}
309
340
}
310
341
342
+ private <T > T executeReactively (String name , Function <ReactiveRedisConnection , T > callback ) {
343
+
344
+ ReactiveRedisConnection connection = getReactiveRedisConnectionFactory ().getReactiveConnection ();
345
+
346
+ try {
347
+ return callback .apply (connection );
348
+ }
349
+ finally {
350
+ connection .closeLater ();
351
+ }
352
+ }
353
+
311
354
private void checkAndPotentiallyWaitUntilUnlocked (String name , RedisConnection connection ) {
312
355
313
356
if (!isLockingCacheWriter ()) {
@@ -333,11 +376,21 @@ private void checkAndPotentiallyWaitUntilUnlocked(String name, RedisConnection c
333
376
}
334
377
}
335
378
379
+ private void assertReactiveRedisConnectionFactory () {
380
+
381
+ Assert .state (this .connectionFactory instanceof ReactiveRedisConnectionFactory ,
382
+ () -> "Cache.retrieve(key) is only supported in Reactive Redis" );
383
+ }
384
+
385
+ private ReactiveRedisConnectionFactory getReactiveRedisConnectionFactory () {
386
+ return (ReactiveRedisConnectionFactory ) this .connectionFactory ;
387
+ }
388
+
336
389
private static byte [] createCacheLockKey (String name ) {
337
390
return (name + "~lock" ).getBytes (StandardCharsets .UTF_8 );
338
391
}
339
392
340
- private boolean isTrue (@ Nullable Boolean value ) {
393
+ private static boolean isTrue (@ Nullable Boolean value ) {
341
394
return Boolean .TRUE .equals (value );
342
395
}
343
396
0 commit comments