基于谓词计划的内存中缓存无效



我在 Map

中存储了 List<CompletableFuture>
 private final Map<UUID, List<CompletableFuture>> hydrationProcesses = new ConcurrentHashMap<>();

当前有一个守护程序线程每30秒运行一次,并删除所有已完成的Futures

有很多TTL无效的实现,我正在寻找基于某些谓词的无效。我想摆脱这个守护程序。

是否有基于某些自定义逻辑的计划缓存无效的盒子解决方案。也许我错过了春季/番石榴的东西?

也许类似于Guava的

CacheBuilder.newBuilder()
  .expireAfterAccess(2,TimeUnit.MILLISECONDS)
  .build(loader);

,但是然后在访问后将所有内容都标记为已过期的所有内容,我需要检查此未来是否已经完成,然后将其从缓存中删除。

我怀疑是否有基于番石榴的解决方案。由于您不专门要求" guava--"解决方案,我想想一想如何解决cache2k的问题。

这是设置的外观:

final long RECHECK_INTERVAL_MILLIS = 30000;
Cache<UUID, CompletableFuture<Void>> cache =
  new Cache2kBuilder<UUID, CompletableFuture<Void>>(){}
    .loader(new AdvancedCacheLoader<UUID, CompletableFuture<Void>>() {
      @Override
      public CompletableFuture<Void> load(UUID key,
                                          long currentTime,
                                          CacheEntry<UUID, CompletableFuture<Void>> currentEntry) {
        return currentEntry != null ? currentEntry.getValue() : null;
      }
    })
    .expiryPolicy(new ExpiryPolicy<UUID, CompletableFuture<Void>>() {
      @Override
      public long calculateExpiryTime(UUID key,
                                      CompletableFuture<Void> value,
                                      long loadTime,
                                      CacheEntry<UUID, CompletableFuture<Void>> oldEntry) {
        return value.isDone() ? NOW : loadTime + RECHECK_INTERVAL_MILLIS;
      }
    })
    .refreshAhead(true)
    .build();

实际上Cache2k具有类似的功能,然后具有Guava或其他缓存。但是,有一些很小的扩展可以允许更复杂的设置。

这里使用的技巧是在通过操作中读取中的缓存,但使加载程序返回当前的高速缓存值。当条目到期后,由于refreshAhead(true)而调用加载程序,但是保留了当前值并再次评估到期策略。您喜欢检查的谓词进入了到期政策。

其他缓存也已经阅读并定制到期,但缺乏"智能装载机"的概念。(AdvancedCacheLoader(可以根据现有的高速缓存值更有效地行事。

我们在生产中使用与此相似的设置。

也有一个缺点。如果使用自定义有效期,则Cache2k使用每个缓存的一个计时线程。这意味着您的额外线程不会消失。将来将增强Cache2k,以在所有缓存中共享一套全局时间用于定时线程。更新: Cache2k的新版本使用计时器的公共线程池。

免责声明:我是cache2k的作者,所以我绝对不能确定基于guava的解决方案。

最新更新