Scaffeine:如何为默认值设置不同的过期时间



Scala应用程序用例:

我们有一个基于Scala的模块,它从全局缓存(Redis(中读取数据,并将数据保存到本地缓存(Scaffeine(中。由于我们希望异步刷新这些数据,我们使用LoadingCache,刷新AfterWrite持续时间设置为刷新窗口2秒。

问题:

在本地缓存中设置值时,我们需要根据redis(全局缓存(中是否存在密钥来设置不同的到期时间。

例如如果键在全局缓存中不存在,我们希望将相同的键保存在本地缓存中,默认值刷新窗口设置为5.分钟。如果全局缓存中存在密钥,我们希望将其存储在本地缓存中,并将刷新窗口设置为30.分钟

样本代码

object LocalCache extends App {
// data being stored in the cache
class DataObject(data: String) {
override def toString: String = {
"[ 'data': '" + this.data + "' ]"
}
}
// loader helper
private def loaderHelper(key: Int): Future[DataObject] = { 
// this method will replace to read the data from Redis Cache
// for now, returns different values per key
if (key == 1) Future.successful(new DataObject("LOADER_HELPER_1"))
else if (key == 2) Future.successful(new DataObject("LOADER_HELPER_2"))
else Future.successful(new DataObject("LOADER_HELPER"))
}
// async loader
private def loader(key: Int): DataObject = {
Try {
Await.result(loaderHelper(key), 1.seconds)
} match {
case Success(result) =>
result
case Failure(exception: Exception) =>
val temp: DataObject = new DataObject("LOADER")
temp
}
}
// initCache
private def initCache(maximumSize: Int): LoadingCache[Int, DataObject] =
Scaffeine()
.recordStats()
.expireAfterWrite(2.second)
.maximumSize(maximumSize)
.build(loader)
// operations on the cache.
val cache: LoadingCache[Int, DataObject] = initCache(maximumSize = 500)
cache.put(1, new DataObject("foo"))
cache.put(2, new DataObject("hoo"))
println("sleeping for 3 secn")
Thread.sleep(3000)
println(cache.getIfPresent(1).toString)
println(cache.getIfPresent(2).toString)
println(cache.get(3).toString)
println("sleeping for 10 secn")
Thread.sleep(10000)
println("waking up from 10 sec sleep")
println(cache.get(1).toString)
println(cache.get(2).toString)
println(cache.get(3).toString)
println("nCache Stats: "+ cache.stats())
}

我看到很多custom.policy可以用来覆盖expiryAfter策略(expiryArterWrite/Update/Access(,但没有找到异步刷新数据的refreshAterWrite策略。任何帮助都是可观的。

p.S.我是Scala和Scaffeine的新手。

遗憾的是,目前还不支持变量刷新。提供该功能存在一个悬而未决的问题。

目前,每个条目可以自定义过期,但自动刷新是固定的。如果您想自己管理,LoadingCache.refresh(key)可能会触发手动刷新。例如,您可以定期迭代条目(通过asMap()视图(,并根据自定义条件手动刷新。

AsyncLoadingCache可能很有用,而不是在缓存加载程序中阻塞未来。缓存将返回运行中的future,在值具体化之前不会使其过期,如果失败,则会将其删除。请注意,synchronous()视图对于异步缓存访问更多操作非常有用。

通过测试,你可能会发现Guava的假股票代码对模拟时间很有用。

最新更新