java Google Guava 的 CacheLoader loadAll() 与 reload() 语义

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10153724/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 23:49:19  来源:igfitidea点击:

Google Guava's CacheLoader loadAll() vs reload() semantics

javacachingguava

提问by spitzanator

Two things I really like about Guava 11's CacheLoader (thanks, Google!) are loadAll(), which allows me to load multiple keys at once, and reload(), which allows me to reload a key asynchronously when it's "stale" but an old value exists. I'm curious as to how they play together, since reload() operates on but a single key.

我非常喜欢 Guava 11 的 CacheLoader(感谢 Google!)的两件事是 loadAll(),它允许我一次加载多个键,以及 reload(),它允许我在键“过时”时异步重新加载它,但是旧值存在。我很好奇它们是如何一起玩的,因为 reload() 只操作一个键。

Concretely, extending the example from CachesExplained:

具体来说,从CachesExplained扩展示例:

LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
   .maximumSize(1000)
   .refreshAfterWrite(1, TimeUnit.MINUTES)
   .build(
       new CacheLoader<Key, Graph>() {
         public Graph load(Key key) { // no checked exception
           return getGraphFromDatabase(key);
         }

         public Map<Key, Graph> loadAll(Iterable<? extends K> keys) {
           return getAllGraphsFromDatabase(keys);
         }

         public ListenableFuture<Graph> reload(final Key key, Graph prevGraph) {
           if (neverNeedsRefresh(key)) {
             return Futures.immediateFuture(prevGraph);
           } else {
             // asynchronous!
             return ListenableFutureTask.create(new Callable<Graph>() {
               public Graph call() {
                 return getGraphFromDatabase(key);
               }
             });
           }
         }
       });

...where "getAllGraphsFromDatabase()" does an aggregate database query rather than length(keys) individual queries.

...其中“getAllGraphsFromDatabase()”执行聚合数据库查询而不是 length(keys) 单个查询。

How do these two components of a LoadingCache play together? If some keys in my request to getAll() aren't present in the cache, they are loaded as a group with loadAll(), but if some need refreshing, do they get reloaded individually with load()? If so, are there plans to support a reloadAll()?

LoadingCache 的这两个组件如何协同工作?如果我对 getAll() 的请求中的某些键不存在于缓存中,它们将作为一个组通过 loadAll() 加载,但如果某些键需要刷新,它们是否会通过 load() 单独重新加载?如果是这样,是否有计划支持 reloadAll()?

回答by Louis Wasserman

Here's how refreshing works.

以下是令人耳目一新的工作原理。

Refreshing on a cache entry can be triggered in two ways:

刷新缓存条目可以通过两种方式触发:

  1. Explicitly, with cache.refresh(key).
  2. Implicitly, if the cache is configured with refreshAfterWriteand the entry is queriedafter the specified amount of time after it was written.
  1. 明确地,与cache.refresh(key).
  2. 隐式地,如果缓存配置了refreshAfterWrite并且在写入后的指定时间量后查询条目。

If an entry that is eligible for reload is queried, then the old value is returned, and a (possibly asynchronous) refresh is triggered. The cache will continue to return the old value for the key while the refresh is in progress. (So if some keys in a getAllrequest are eligible for refresh, their old values will be returned, but the values for those keys will be (possibly asynchronously) reloaded.)

如果查询符合重新加载条件的条目,则返回旧值,并触发(可能是异步的)刷新。在刷新过程中,缓存将继续返回键的旧值。(因此,如果getAll请求中的某些键符合刷新条件,它们的旧值将被返回,但这些键的值将(可能异步)重新加载。)

The defaultimplementation of CacheLoader.reload(key, oldValue)just returns Futures.immediateFuture(load(key)), which (synchronously) recomputes the value. More sophisticated, asynchronous implementations are recommended if you expect to be doing cache refreshes.

默认实现CacheLoader.reload(key, oldValue)just 返回Futures.immediateFuture(load(key)),它(同步)重新计算值。如果您希望进行缓存刷新,建议使用更复杂的异步实现。

I don't think we're inclined to provide reloadAllat the moment. I suspect it's possible, but things are complicated enough as it is, and I think we're inclined to wait until we see specific demand for such a thing.

我认为我们目前不倾向于提供reloadAll。我怀疑这是可能的,但事情已经足够复杂了,我认为我们倾向于等到我们看到对这种事情的具体需求。