咖啡因。当AsyncLoader无法刷新时,使用陈旧的值。

问题描述 投票:0回答:1

我想配置我的 Caffeine 缓存,当加载器无法刷新缓存时,返回陈旧的结果。下面的Kotlin代码演示了这个案例。

    @Test
    fun `completeble future`() = runBlocking {
        val cache = Caffeine.newBuilder()
            .refreshAfterWrite(Duration.ofSeconds(1))
            .expireAfterWrite(Duration.ofSeconds(1))
            .buildAsync<String, String> { key: String, executor ->
                GlobalScope.future(executor.asCoroutineDispatcher()) {
                    throw Exception("== Error ==")
                }
            }

        cache.put("id", CompletableFuture.completedFuture("value"))

        delay(2000)

        assertEquals("value", cache.get("id").await())
    }

我希望这个测试能通过,但却得到了以下错误。

WARNING: Exception thrown during asynchronous load
java.lang.Exception: == Error ==
    at fsra.manager.TranslationManagerImplTest$completeble future$1$cache$1$1.invokeSuspend(TranslationManagerImplTest.kt:93)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:241)
    at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426)
    at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
    at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)




java.lang.Exception: == Error ==

    at fsra.manager.TranslationManagerImplTest$completeble future$1$cache$1$1.invokeSuspend(TranslationManagerImplTest.kt:93)
    at |b|b|b(Coroutine boundary.|b(|b)
    at fsra.manager.TranslationManagerImplTest$completeble future$1.invokeSuspend(TranslationManagerImplTest.kt:101)
Caused by: java.lang.Exception: == Error ==
    at fsra.manager.TranslationManagerImplTest$completeble future$1$cache$1$1.invokeSuspend(TranslationManagerImplTest.kt:93)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:241)
    at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426)
    at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
    at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)

我是用Kotlin写的代码,但我不认为这个问题与Kotlin coroutines有关。我想配置Caffeine在刷新时不抛出,而是返回缓存中的前一个结果。

java kotlin kotlin-coroutines caffeine caffeine-cache
1个回答
2
投票

缓存设置为1秒后过期条目,测试等待2秒。下一次调用就会因为条目无法使用而强制重新加载,你就会抛出一个异常。

当大于或等于过期时间时,刷新没有效果。当小于时,条目是陈旧的,但可以使用,所以会返回并异步重新加载。这是为了让受欢迎的项目,比如配置,可以留在缓存中,而不会在重新加载时受到周期性的惩罚。不受欢迎的项目是指在到期时间间隔内没有被访问的项目,允许被驱逐。如果刷新无法成功,那么过期就会启动,条目就会被放弃,因为过期设置了它被认为可以使用的最大时间。

一个更大的过期值,比如5秒,就可以通过你的测试。如果您的使用情况是周期性地盲目重载所有缓存的内容,您可以使用常规的 Map 和a ScheduledExecutorService 来刷新它。

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