是否有可能将Guava Cache(或其他库)的行为配置为:如果需要重新加载,请返回上一个条目,并在后台重新加载(请参见规格)

问题描述 投票:3回答:2

我想拥有一个像这样的缓存:

  • A。如果未缓存请求:加载并返回结果。
  • B。如果请求已缓存,则尚未过期:返回结果。
  • C。如果请求已缓存,则已过期:立即返回旧结果,开始重新加载结果(异步)
  • D。如果请求已缓存,已过期,则重新加载已在运行:请立即返回旧结果。
  • E。如果重新加载失败(异常):继续将先前成功的加载结果返回给请求。

(重新加载失败后(案例E),在案例C之后处理了下一个请求。

((如果情况A以异常结束,则引发异常)

有人知道现有的实现,还是我必须自己实现?

java caching guava
2个回答
1
投票

cache2k中,我完全实现了您上述的行为。这是使用这些功能构建缓存的方法:

  CacheBuilder.newCache(Key.class, Value.class)
    .name("myCache")
    .source(new YourSourceImplementation())
    .backgroundRefresh(true)
    .suppressExceptions(true)
    .maxSize(7777) // maximum entries in the cache
    .expiryDuration(60, TimeUnit.SECONDS)
    .exceptionExpiryDuration(15, TimeUnit.SECONDS)
    .build();

exipryDuration是该值在插入或修改后被视为有效的持续时间。 exceptionExpiryDuration的单独设置是发生异常后尝试下一次刷新的时间。

如果发生异常,但是没有有效的条目,则在exceptionExpiryDuration时间内将异常缓存并重新抛出。

您还可以动态计算有效期,例如基于异常类型。更多信息在博客条目About caching exceptions

使用backgroundRefresh,条目过期后将刷新。如果在有效期内刷新后没有访问权限,则该条目将不再刷新,最终被逐出。

[不幸的是,我确实在适当地记录所有这些有用功能方面落后。如果您还有其他疑问,可以使用标签cache2k。如果您需要一些改进,请在GitHub上打开一个问题。

该代码在我们的生产应用程序中运行了大约一年。实际上,suppressExceptions始终是默认值。它非常有帮助,例如如果网络中断很短。

BTW:同时,我将这些语义包含在术语[[缓存弹性]]下。


© www.soinside.com 2019 - 2024. All rights reserved.