是否可以将Guava Cache(或其他库)行为配置为:如果要重新加载时间,则返回上一个条目,在后台重新加载(请参阅规范)

时间:2015-11-17 07:31:52

标签: java caching guava

我想要一个像这样工作的缓存:

  • 甲。如果请求未缓存:加载并返回结果。
  • B中。如果缓存请求,则表示尚未过期:返回结果。
  • ℃。如果请求被缓存,则已过期:开始重新加载结果,立即返回旧结果。
  • d。如果请求已缓存,已过期,则重新加载已在运行:立即返回旧结果。
  • 电子。如果重新加载失败(例外):继续将先前成功的加载结果返回给请求。

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

(如果案例A以异常结束,则抛出异常)

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

1 个答案:

答案 0 :(得分: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:与此同时,我将这些语义包含在术语缓存弹性中。