【发布时间】:2018-08-14 18:15:58
【问题描述】:
如何执行非阻塞的获取/计算查找并避免缓存踩踏。
这是一个不会踩踏,而是阻塞的例子。
public static <KEY, VALUE> Mono<VALUE> lookupAndWrite(
Map<KEY, Signal<? extends VALUE>> cacheMap, KEY key, Mono<VALUE> mono) {
return Mono.defer(() -> Mono.just(cacheMap.computeIfAbsent(key, k ->
mono.materialize().block())).dematerialize());
}
这是一个不会阻塞,但可以踩踏的例子。
public static <KEY, VALUE> MonoCacheBuilderCacheMiss<KEY, VALUE> lookup(
Function<KEY, Mono<Signal<? extends VALUE>>> reader, KEY key) {
return otherSupplier -> writer -> Mono.defer(() ->
reader.apply(key)
.switchIfEmpty(otherSupplier.get()
.materialize()
.flatMap(signal -> writer.apply(key, signal)
)
)
.dematerialize());
}
有没有不会踩踏或阻塞的方法?只在自己的调度程序上订阅阻塞调用有意义吗?
【问题讨论】:
-
在这里使用
AsyncLoadingCache有意义吗?然后你不会在计算过程中阻塞,缓存会在未来值完成(成功或错误)时添加回调。 (P.S.AsyncCache将在下一个版本中,但很容易模仿) -
@BenManes 我不确定。密钥没有包含足够的信息来知道如何加载数据(也许这无关紧要)。
-
您可以避免
get(key)调用并让加载程序抛出异常,以降级为临时AsyncCache。然后你可以用类似cache.get(key, k -> mono.toFuture())的方式编写你的代码 -
由于 SO 不适合讨论,如果您愿意,我们可以将其带回您的 github issue。
-
@BenManes 如果您认为这是最好的。我在这里提出它是为了让更多人关注它,因为这似乎是一个非常常见的问题,但尚未提出(对于这个框架)。
标签: java-8 project-reactor caffeine