scala - 为什么scala缓存要求我定义TTL两次?
问题描述
所以我一直在努力跟上 scala 缓存的速度。我正在浏览这个文档
https://cb372.github.io/scalacache/docs/
private val thisToThatCache =
CaffeineCache(
Caffeine.newBuilder
.maximumSize(4096)
.expireAfterWrite(4, TimeUnit.HOURS)
.build[String, String)
和这个缓存调用
import scalacache.modes.try_._
import scala.collection.JavaConverters._
thisToThatCache.caching(thisStr)(ttl = 4.hours)(
fetchThatForGivenThis(thisStr)
)
请注意,我已经定义了两次 TTL,一次在缓存调用中使用 4.hours,另一次基于 4 TimeUnit.Hours
这有点奇怪,所以我开始研究 CaffeineCache 的实现
我看着这个
而且我意识到,无论我将 expire After Write 值放在什么位置,如果缓存 ttl 值已过期(至少应该如此),getter 都会认为工件已过期。
AFAIK 底层缓存定义了驱逐。
所以我的问题是
- scala缓存的设计决策是什么,对TTL有两种不同的定义。即驱逐和到期的概念是不连贯的并分别定义?
为了解释我的意思 doPut https://github.com/cb372/scalacache/blob/433d07ddb1249d7e6ec13fe7584a3d785be8d44d/modules/caffeine/src/main/scala/scalacache/caffeine/CaffeineCache.scala#L42的具体示例在这里创建了一个 Entry 对象并将其放入。条目定义 isExpired https://github.com/cb372/scalacache/blob/dd7f9988b3b1cab20ba2a9649a51a36210065607/modules/core/shared/src/main/scala/scalacache/Entry.scala#L13,如果expiresAt 是无。最后是 doGet:https ://github.com/cb372/scalacache/blob/433d07ddb1249d7e6ec13fe7584a3d785be8d44d/modules/caffeine/src/main/scala/scalacache/caffeine/CaffeineCache.scala#L29方法检查其是否过期(如果之前的键的 doPut 已 expiredAt 为 None,则它评估为 false)并返回 None,因为它被认为已过期。请注意,它没有咨询 expireAfter... 超时。因此,如果我通过 None,它应该始终评估为未找到。
- 如果 expireAfterWrite < ttl 在缓存中的行为是什么。到期是要遵守 expireAfterWrite 还是取决于实现(即底层缓存仅在缓存达到有界大小时才延迟驱逐对象)?
解决方案
caching("benjamin")(ttl = None)
ttl
是一个Option[Duration]
,所以它应该定义在
expireAfterWrite(4, TimeUnit.HOURS)
同时,当您使用时:
caching("benjamin")(ttl = 4.hours) // implicit conversion to Some(4.hours)
您可以覆盖特定值的默认值。实现细节取决于实现:
// abstract def that need to be implemented by particular cache implemetation
protected def doPut[F[_]](key: String, value: V, ttl: Option[Duration])(implicit mode: Mode[F]): F[Any]
正如你所看到的,它接收到可选的 ttl,它可以用它做任何它想做的事情(甚至忽略)。默认值必须在其他地方提供,我们可以在文档中看到,这就是 builder 使用expireAfterWrite
.
长话短说,您不必提供 ttl 两次。None
如果您不想覆盖该值,请通过。
推荐阅读
- java - 使用 java 编程的具有巨大结果集的长时间运行查询
- javascript - 在 react.js 中从一个组件创建两个组件的问题
- sqlite - SQLite - 将同一表中多行的值插入另一个表中的单行
- c++ - 从自定义类中获取对象向量中的最大元素
- bash - 将 Bash 变量设置为另一个会导致操作数错误
- vb.net - 在 Windows 10 中使用我的 VB 2008 应用程序时,它崩溃了
- javascript - 在 return 语句中解构
- algorithm - 运行时间和空间复杂度修改合并排序
- javascript - 如何制作表格jQuery分页逻辑
- javascript - 按下按钮时在 URL 中发布数据