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

Commit

Permalink
feat: add SpringValueCache for easy creation of ValueCache that use S…
Browse files Browse the repository at this point in the history
…pring Caches
  • Loading branch information
bsara committed Sep 19, 2023
1 parent 8ef25cf commit 4c21f5f
Showing 1 changed file with 76 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package graphql.kickstart.spring.cache;

import static java.util.concurrent.CompletableFuture.runAsync;
import static java.util.concurrent.CompletableFuture.supplyAsync;

import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import lombok.RequiredArgsConstructor;
import org.dataloader.ValueCache;
import org.springframework.cache.Cache;
import org.springframework.cache.Cache.ValueWrapper;

/**
* A {@link ValueCache} which uses a Spring {@link Cache} for caching.
*
* @see <a
* href="https://www.graphql-java.com/documentation/batching/#per-request-data-loaders">GraphQL Java
* docs</a>
*/
@RequiredArgsConstructor
public class SpringValueCache<K, V> implements ValueCache<K, V> {

private final Cache cache;
private Function<K, ?> keyTransformer;

@Override
public CompletableFuture<V> get(K key) {
return supplyAsync(() -> {
Object finalKey = this.getKey(key);
ValueWrapper valueWrapper = this.cache.get(finalKey);

if (valueWrapper == null) {
throw new CacheEntryNotFoundException(this.cache.getName(), finalKey);
}

return (V) valueWrapper.get();
});
}

@Override
public CompletableFuture<V> set(K key, V value) {
return supplyAsync(() -> {
this.cache.put(this.getKey(key), value);
return value;
});
}

@Override
public CompletableFuture<Void> delete(K key) {
return runAsync(() -> this.cache.evictIfPresent(this.getKey(key)));
}

@Override
public CompletableFuture<Void> clear() {
return runAsync(this.cache::invalidate);
}

public <KFinal> SpringValueCache<K, V> setKeyTransformer(Function<K, KFinal> transformer) {
this.keyTransformer = transformer;
return this;
}

private Object getKey(K key) {
return (
this.keyTransformer == null
? key
: this.keyTransformer.apply(key)
);
}

public static class CacheEntryNotFoundException extends RuntimeException {
public CacheEntryNotFoundException(String cacheName, Object key) {
super("Entry could not be found in cache named \"" + cacheName + "\" for key: " + key);
}
}
}

0 comments on commit 4c21f5f

Please sign in to comment.