Асинхронное кэширование с использованием кофеина

#java #caching #future #caffeine

#java #кэширование #будущее #кофеин

Вопрос:

Я наткнулся на асинхронное кэширование с использованием библиотеки Caffeine. Следующее https://www.programcreek.com/java-api-examples/?api=com.github.benmanes.caffeine.cache .AsyncCacheLoader, у меня есть следующий фрагмент кода:

 import com.github.benmanes.caffeine.cache.AsyncCacheLoader;
import com.github.benmanes.caffeine.cache.AsyncLoadingCache;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.Weigher;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

public class CacheManager {
private static AsyncLoadingCache<String, Object> loader;

public static void initLoadingCache(<datatype> obj) {
    if (loader == null) {
        loader = Caffeine.newBuilder()
                .concurrencyLevel(10)
                .expireAfterWrite(60, TimeUnit.MINUTES) // Cache will expire after 60 minutes
                .buildAsync(new AsyncCacheLoader<String, Object>() { // Build the CacheLoader
                    @Override
                    public CompletableFuture<Object> asyncLoad(String key, Executor executor) throws Exception{
                        Object temp = obj.getTemp(key); // my function which does processing
                        if (temp == null)  LOGGER.error("Not found");
                        return temp;
                    }
                });
        }
    }
}

public Object getTemp(String key) {
    Query query = somequery();
    List<Object> val = query.getResultList();
    return val.get(0);
}
  
  1. Очевидно, что приведенный выше код будет содержать ошибку, поскольку я возвращаю temp то, Object что ожидает функция CompletableFuture<Object> . Как я могу этого добиться? Я предполагаю, что getTemp() это тоже нужно вернуть ListenableFuture<> (https://www.programcreek.com/java-api-examples/?code=Netflix/titus-control-plane/titus-control-plane-master/titus-supplementary-component/tasks-publisher/src/main/java/com/netflix/titus/supplementary/taskspublisher/TitusClientImpl.java ) но я не уверен, как я могу добиться этого, поскольку у него есть запросы к БД.

Комментарии:

1. Я думаю, вы хотите использовать CacheLoader which автоматически перенесет вашу логику в будущее.

2. @BenManes разве это не мой loader asyncacheloader ответ? Я не могу понять, что я должен добавить buildAsync() на вашу страницу github. или я должен просто поставить .buildAsync(key->obj.getTemp(key))

3. Если (как я понимаю) вашу проблему «просто» объект-> класс CompletableFuture<?>тогда вы можете создать ее, с: CompletableFuture<Object> cf = new CompletableFuture(); ..и как только у вас есть свой «объект»(синхронно), вы можете вызвать cf.complete(temp); ..и return cf;

4. @xerx593 CompletableFuture.completedFuture (temp) — это то, о чем я думаю, но я не уверен, что более эффективный способ сделать по сравнению с тем, что говорит БенМанес.

5. @amyJ Разработчик принимает CacheLoader or AsyncCacheLoader , где первое может быть немного проще для вас. В противном случае вы могли бы вернуть a CompletableFuture.supplyAs(...) , если хотите напрямую создать будущее.