Я пытаюсь добавить пользовательский слой кэша, используя HazelCast, но я не уверен, как реализовать описанный ниже метод
public <T> CompletionStage<T> getOrElseUpdate(String key, Callable<CompletionStage<T>> callable, int expiration)
Ниже приведен мой полный класс.Контракт описанного выше метода заключается в том, чтобы найти элемент на основе ключа из кэша, иначе выполнить блок и вернуть этап завершения с добавленным элементом.
Я пробовал несколько способов сделать это, но много типов стертоошибки и неконверсия Callable<CompletionStage<T>>
привели меня в замешательство.
import akka.Done;
import com.hazelcast.core.IMap;
import play.cache.AsyncCacheApi;
import java.util.concurrent.*;
import static java.util.concurrent.CompletableFuture.runAsync;
import static java.util.concurrent.CompletableFuture.supplyAsync;
public class MyAsyncCache<T> implements AsyncCacheApi {
IMap<String, T> internalMapCache;
@Override
public <T> CompletionStage<T> get(String key) {
return supplyAsync( () -> {
T t = (T) internalMapCache.get(key);
return t;});
}
@Override
public <T> CompletionStage<T> getOrElseUpdate(String key, Callable<CompletionStage<T>> callable, int expiration) {
supplyAsync( () -> {
T t = (T) internalMapCache.get(key);
if(t == null){
//callable.call()
}else {
return t;
}
}
);
}
@Override
public <T> CompletionStage<T> getOrElseUpdate(String key, Callable<CompletionStage<T>> block) {
}
@Override
public CompletionStage<Done> set(String key, Object value, int expiration) {
return set(key,value);
}
@Override
public CompletionStage<Done> set(String key, Object value) {
return supplyAsync( () -> {
internalMapCache.set(key, value);
return Done.getInstance();
});
}
@Override
public CompletionStage<Done> remove(String key) {
return supplyAsync( () -> {
internalMapCache.remove(key);
return Done.getInstance();
});
}
@Override
public CompletionStage<Done> removeAll() {
return supplyAsync( () -> {
internalMapCache.clear();
return Done.getInstance();
});
}
}
Любая помощь, ведущая к решению этой проблемы, будет принята с благодарностью.
Обновление
- Удален тип из класса
MyAsyncCache<T>
Не нужно быть универсальным на этом уровне, поэтому его только MyAsyncCache
сейчас - IЯ добавил мою реализацию метода
getOrElseUpdate
, как показано ниже, но у меня есть ощущение, что ее можно еще улучшить.
Метод обновлен следующим образом:
@Override
public <T> CompletionStage<T> getOrElseUpdate(String key, Callable<CompletionStage<T>> callable, int expiration) {
CompletableFuture<T> uCompletableFuture = supplyAsync(() -> {
T obj;
if (!mapBased.containsKey(key)) {
try {
Future<CompletionStage<T>> submit = Executors.newSingleThreadExecutor()
.submit(callable);
obj = submit.get().toCompletableFuture().get();
} catch (Exception e) {
e.printStackTrace();
return null;
}
} else {
obj = (T) mapBased.get(key);
}
return obj;
});
return uCompletableFuture;
}
Как я могу улучшить вышеуказанный метод?