scala - 如何在“Scala”中为 Caffeine LoadingCache 编写缓存加载器以使“refreshAfterWrite”正常工作
问题描述
Scala 应用程序用例:
我们有一个基于 Scala 的模块,它从全局缓存(Redis)中读取数据并将其保存到本地缓存(Caffeine LoadingCache)中。由于我们希望这些数据异步刷新,我们使用 LoadingCache 并将 refreshAfterWrite 持续时间设置为 2.second 的刷新窗口。
问题: 不是问题,但需要有关以下代码的帮助,该代码给出警告并编译时错误
警告:对于build
方法,它给出警告为Implements member load in CacheLoader (com.github.benmanes.caffeine.cache)
编译时错误1: type arguments [Int,redisToCaffeine.DataObject] conform to the bounds of none of the overloaded alternatives of value build: [K1 <: Object, V1 <: Object](x$1: com.github.benmanes.caffeine.cache.CacheLoader[_ >: K1, V1])com.github.benmanes.caffeine.cache.LoadingCache[K1,V1] <and> [K1 <: Object, V1 <: Object]()com.github.benmanes.caffeine.cache.Cache[K1,V1] .build[Int, DataObject](key => loader(key))
编译时错误2: wrong number of type parameters for overloaded method value build with alternatives: [K1 <: Object, V1 <: Object](x$1: com.github.benmanes.caffeine.cache.CacheLoader[_ >: K1, V1])com.github.benmanes.caffeine.cache.LoadingCache[K1,V1] <and> [K1 <: Object, V1 <: Object]()com.github.benmanes.caffeine.cache.Cache[K1,V1] .build[Int, DataObject](key => loader(key))
代码:
package redisToCaffeine
import scala.concurrent.duration._
import com.github.benmanes.caffeine.cache.{ CacheLoader, Caffeine, LoadingCache }
import com.twitter.finagle.stats.InMemoryStatsReceiver
import javax.annotation.Nullable
import redisToCaffeine.CacheImplicits.StatsReportingCaffeineCache
class LocalDealService {
class DataObject(data: String) {
override def toString: String = {
"[ 'data': '" + this.data + "' ]"
}
}
val defaultCacheExpireDuration: FiniteDuration = 2.second
val stats: InMemoryStatsReceiver = new InMemoryStatsReceiver
// loader helper
@Nullable
@throws[Exception]
protected def loader(key: Int): DataObject = { // this will replace to read the data from Redis Cache
new DataObject(s"LOADER_HELPER_$key")
}
def initCache(maximumSize: Int = 5): LoadingCache[Int, DataObject] = {
Caffeine
.newBuilder()
.maximumSize(maximumSize)
.refreshAfterWrite(defaultCacheExpireDuration.length, defaultCacheExpireDuration.unit)
.recordStats()
.build[Int, DataObject](key => loader(key))
.enableCacheStatsReporting("deal-service", stats)
}
}
我是 Scala 和 Caffeine 的新手,所以不确定我做错了什么;我尝试了这里和这里提到的不同方法来编写加载程序,但没有任何效果(主要是在 Java 中)。围绕 Scala 边界的少量研究在这里没有任何帮助。请帮忙。
解决方案
取决于这里使用的是哪个 Scala 版本。
尽管 Scala(2.12 及更高版本)函数支持转换为 Java SAM,但这些仅在明确需要时才完成。因此,如果您使用的是 Scala 2.12 或更高版本,您可以显式要求编译器将 Scala 函数转换为 SAM,
另外,不要Int
用作缓存的键。虽然它会因为隐式转换而起作用Integer
,但这不是一个好习惯。
def initCache(maximumSize: Int = 5): LoadingCache[Integer, DataObject] = {
Caffeine
.newBuilder()
.maximumSize(maximumSize)
.refreshAfterWrite(defaultCacheExpireDuration.length, defaultCacheExpireDuration.unit)
.recordStats()
.build[Integer, DataObject]((key => loader(key)): CacheLoader[Integer, DataObject])
.enableCacheStatsReporting("deal-service", stats)
}
如果您正在处理旧的 Scala 版本,那么就忘记 SAM 的存在并使用旧样式。
def initCache(maximumSize: Int = 5): LoadingCache[Integer, DataObject] = {
Caffeine
.newBuilder()
.maximumSize(maximumSize)
.refreshAfterWrite(defaultCacheExpireDuration.length, defaultCacheExpireDuration.unit)
.recordStats()
.build[Int, DataObject](new CacheLoader[Integer, DataObject] {
override def load(key: Integer): DataObject = loader(key)
})
.enableCacheStatsReporting("deal-service", stats)
}
推荐阅读
- java - 休眠多对一关系注释
- python-3.x - cv2的问题:C:\projects\opencv-python\opencv\modules\highgui\src\window.cpp:627: error: (-2:Unspecified error) 功能没有实现
- ksqldb - ksql rest api创建并在json中获取输出
- java - UberJar 不起作用:Intellij Maven java.lang.NoClassDefFoundError with Jackson YAML
- javascript - Javascript:jQuery回调的等待循环
- javascript - 将数组从js发送到php
- r - 在热图的每一列中可视化多个变量
- javascript - 选择图像源
- laravel - 为什么,请求返回符号 - '?
- oauth - 使用 base64 编码生成 Oauth 授权令牌