Skip to content
This repository was archived by the owner on Dec 19, 2023. It is now read-only.

Commit 311a138

Browse files
authored
Merge pull request #964 from bsara/value-cache-helper
feat: added SpringValueCache for easy creation of data loader ValueCache objects that utilize Spring Caches under the hood
2 parents d6e21f3 + 01bd575 commit 311a138

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package graphql.kickstart.spring.cache;
2+
3+
import static java.util.concurrent.CompletableFuture.runAsync;
4+
import static java.util.concurrent.CompletableFuture.supplyAsync;
5+
6+
import java.util.concurrent.CompletableFuture;
7+
import java.util.function.Function;
8+
import lombok.RequiredArgsConstructor;
9+
import org.dataloader.ValueCache;
10+
import org.springframework.cache.Cache;
11+
import org.springframework.cache.Cache.ValueWrapper;
12+
13+
/**
14+
* A {@link ValueCache} which uses a Spring {@link Cache} for caching.
15+
*
16+
* @see <a
17+
* href="https://www.graphql-java.com/documentation/batching/#per-request-data-loaders">GraphQL Java
18+
* docs</a>
19+
*/
20+
@RequiredArgsConstructor
21+
public class SpringValueCache<K, V> implements ValueCache<K, V> {
22+
23+
private final Cache cache;
24+
private Function<K, ?> keyTransformer;
25+
26+
@Override
27+
public CompletableFuture<V> get(K key) {
28+
return supplyAsync(() -> {
29+
Object finalKey = this.getKey(key);
30+
ValueWrapper valueWrapper = this.cache.get(finalKey);
31+
32+
if (valueWrapper == null) {
33+
throw new CacheEntryNotFoundException(this.cache.getName(), finalKey);
34+
}
35+
36+
return (V) valueWrapper.get();
37+
});
38+
}
39+
40+
@Override
41+
public CompletableFuture<V> set(K key, V value) {
42+
return supplyAsync(() -> {
43+
this.cache.put(this.getKey(key), value);
44+
return value;
45+
});
46+
}
47+
48+
@Override
49+
public CompletableFuture<Void> delete(K key) {
50+
return runAsync(() -> this.cache.evictIfPresent(this.getKey(key)));
51+
}
52+
53+
@Override
54+
public CompletableFuture<Void> clear() {
55+
return runAsync(this.cache::invalidate);
56+
}
57+
58+
public <KFinal> SpringValueCache<K, V> setKeyTransformer(Function<K, KFinal> transformer) {
59+
this.keyTransformer = transformer;
60+
return this;
61+
}
62+
63+
private Object getKey(K key) {
64+
return (
65+
this.keyTransformer == null
66+
? key
67+
: this.keyTransformer.apply(key)
68+
);
69+
}
70+
71+
public static class CacheEntryNotFoundException extends RuntimeException {
72+
public CacheEntryNotFoundException(String cacheName, Object key) {
73+
super("Entry could not be found in cache named \"" + cacheName + "\" for key: " + key);
74+
}
75+
}
76+
}

0 commit comments

Comments
 (0)