使用 AsyncCacheApi 播放框架 |在 Java 中为测试实施缓存
Play Framework using AsyncCacheApi | Implement Cache for tests in Java
我目前正在尝试在 Java 中实现 play.api.cache.AsyncCacheApi。由于通用参数,我在实现 get 和 getOrElseUpdate 时遇到了很大的麻烦。
我的class:
package common;
import akka.Done;
import net.sf.ehcache.Element;
import play.api.cache.AsyncCacheApi;
import play.api.cache.SyncCacheApi;
import scala.Function0;
import scala.Option;
import scala.concurrent.Future;
import scala.concurrent.duration.Duration;
import scala.reflect.ClassTag;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import static scala.compat.java8.FutureConverters.toScala;
public class InMemoryCacheJava implements AsyncCacheApi {
final Map<String, Element> cache = new HashMap<>();
@Override
public SyncCacheApi sync() {
return null;
}
@Override
public Future<Done> set(String key, Object value, Duration expiration) {
return toScala(CompletableFuture.supplyAsync(
() -> {
final Element element = new Element(key, value);
if (expiration == Duration.Zero()) {
element.setEternal(true);
}
element.setTimeToLive(Math.toIntExact(expiration.toSeconds()));
cache.put(key, element);
return Done.getInstance();
}
));
}
@Override
public Future<Done> remove(String key) {
return toScala(CompletableFuture.supplyAsync(
() -> {
cache.remove(key);
return Done.getInstance();
}
));
}
@Override
public <T> Future<Option<T>> get(String key, ClassTag<T> evidence) {
return null;
}
@Override
public Future<Done> removeAll() {
return toScala(CompletableFuture.supplyAsync(
() -> {
cache.clear();
return Done.getInstance();
}
));
}
@Override
public <A> Future<A> getOrElseUpdate(String key, Duration expiration, Function0<Future<A>> orElse, ClassTag<A> evidence) {
return null;
}
}
这样做正确吗?我使用这个 API 是因为在我的生产代码中我使用的是实现 DefaultAsyncCacheApi 并且我想使用内部缓存(如地图)测试我的代码。我错过了什么?
我决定改用 Java API,并在内存缓存中实现了自己的缓存。
我的工作代码(它可能不是最好的实现),如果它可以帮助:
package common;
import akka.Done;
import play.cache.AsyncCacheApi;
import java.util.HashMap;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
public class InMemoryCache implements AsyncCacheApi {
private final HashMap<String, Object> cache = new HashMap();
@Override
public <T> CompletionStage<T> get(String key) {
return CompletableFuture.completedFuture((T) this.cache.get(key));
}
@Override
public <T> CompletionStage<T> getOrElseUpdate(String key, Callable<CompletionStage<T>> block, int expiration) {
return this.getOrElseUpdate(key, block);
}
@Override
public <T> CompletionStage<T> getOrElseUpdate(String key, Callable<CompletionStage<T>> block) {
final Object o = this.cache.get(key);
if (Objects.isNull(o)) {
try {
return block.call();
} catch (Exception e) {
e.printStackTrace();
}
}
return CompletableFuture.completedFuture((T) o);
}
@Override
public CompletionStage<Done> set(String key, Object value, int expiration) {
return this.set(key, value);
}
@Override
public CompletionStage<Done> set(String key, Object value) {
return CompletableFuture.supplyAsync(
() -> {
this.cache.put(key, value);
return Done.getInstance();
}
);
}
@Override
public CompletionStage<Done> remove(String key) {
return CompletableFuture.supplyAsync(
() -> {
this.cache.remove(key);
return Done.getInstance();
}
);
}
@Override
public CompletionStage<Done> removeAll() {
return CompletableFuture.supplyAsync(() -> {
this.cache.clear();
return Done.getInstance();
});
}
}
我目前正在尝试在 Java 中实现 play.api.cache.AsyncCacheApi。由于通用参数,我在实现 get 和 getOrElseUpdate 时遇到了很大的麻烦。
我的class:
package common;
import akka.Done;
import net.sf.ehcache.Element;
import play.api.cache.AsyncCacheApi;
import play.api.cache.SyncCacheApi;
import scala.Function0;
import scala.Option;
import scala.concurrent.Future;
import scala.concurrent.duration.Duration;
import scala.reflect.ClassTag;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import static scala.compat.java8.FutureConverters.toScala;
public class InMemoryCacheJava implements AsyncCacheApi {
final Map<String, Element> cache = new HashMap<>();
@Override
public SyncCacheApi sync() {
return null;
}
@Override
public Future<Done> set(String key, Object value, Duration expiration) {
return toScala(CompletableFuture.supplyAsync(
() -> {
final Element element = new Element(key, value);
if (expiration == Duration.Zero()) {
element.setEternal(true);
}
element.setTimeToLive(Math.toIntExact(expiration.toSeconds()));
cache.put(key, element);
return Done.getInstance();
}
));
}
@Override
public Future<Done> remove(String key) {
return toScala(CompletableFuture.supplyAsync(
() -> {
cache.remove(key);
return Done.getInstance();
}
));
}
@Override
public <T> Future<Option<T>> get(String key, ClassTag<T> evidence) {
return null;
}
@Override
public Future<Done> removeAll() {
return toScala(CompletableFuture.supplyAsync(
() -> {
cache.clear();
return Done.getInstance();
}
));
}
@Override
public <A> Future<A> getOrElseUpdate(String key, Duration expiration, Function0<Future<A>> orElse, ClassTag<A> evidence) {
return null;
}
}
这样做正确吗?我使用这个 API 是因为在我的生产代码中我使用的是实现 DefaultAsyncCacheApi 并且我想使用内部缓存(如地图)测试我的代码。我错过了什么?
我决定改用 Java API,并在内存缓存中实现了自己的缓存。
我的工作代码(它可能不是最好的实现),如果它可以帮助:
package common;
import akka.Done;
import play.cache.AsyncCacheApi;
import java.util.HashMap;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
public class InMemoryCache implements AsyncCacheApi {
private final HashMap<String, Object> cache = new HashMap();
@Override
public <T> CompletionStage<T> get(String key) {
return CompletableFuture.completedFuture((T) this.cache.get(key));
}
@Override
public <T> CompletionStage<T> getOrElseUpdate(String key, Callable<CompletionStage<T>> block, int expiration) {
return this.getOrElseUpdate(key, block);
}
@Override
public <T> CompletionStage<T> getOrElseUpdate(String key, Callable<CompletionStage<T>> block) {
final Object o = this.cache.get(key);
if (Objects.isNull(o)) {
try {
return block.call();
} catch (Exception e) {
e.printStackTrace();
}
}
return CompletableFuture.completedFuture((T) o);
}
@Override
public CompletionStage<Done> set(String key, Object value, int expiration) {
return this.set(key, value);
}
@Override
public CompletionStage<Done> set(String key, Object value) {
return CompletableFuture.supplyAsync(
() -> {
this.cache.put(key, value);
return Done.getInstance();
}
);
}
@Override
public CompletionStage<Done> remove(String key) {
return CompletableFuture.supplyAsync(
() -> {
this.cache.remove(key);
return Done.getInstance();
}
);
}
@Override
public CompletionStage<Done> removeAll() {
return CompletableFuture.supplyAsync(() -> {
this.cache.clear();
return Done.getInstance();
});
}
}