我有類似以下的內容,用於在Redis中爲使用http4s,Argonaut和Slick的Scala應用程序緩存JSON響應,並且想確認它的工作方式如何。我們的想法是,如果一個Redis的key
沒有被發現,然後打電話給定fallback
方法從原始來源(MySQL的)獲取數據並緩存以備將來的請求,否則跳過的MySQL:是否需要調用Future方法參數「by-name」?
/** Get from MySQL */
def getThingsFromDatabase(matchingId: Int): Future[Seq[Thing]] = {
println("getThingsFromDatabase")
val query = things.filter(_.fieldId === matchingId)
db.run(query.result)
}
/** Get from Redis, else MySQL via `fallback` */
def getThingsFromRedisOrDatabase(key: String,
fallback: Future[Seq[Thing]]):
Future[argonaut.Json] = {
val stored = redis.get(key)
stored match {
// Data exists, return from redis
case Some(s) => {
Parse.parse(s) match { // convert string to Json
case Right(r) => Future { r } // Json => Future[argonaut.Json]
case Left(l) => println(l) // error
}
}
// Data does not exist, get from database and store
case None() => {
val data = fallback.map(_.toList.asJson)
data map { redis.set(key, _) }
data // Future[argonaut.Json]
}
}
}
// GET /things/12
Ok(getThingsFromRedisOrDatabase("things:12", getThingsFromDatabase(12)))
然而這工作,上述代碼將始終打印「getThingsFromDatabase」,無論Redis中是否存在數據,因爲getThingsFromDatabase(12)
在作爲參數調用時執行。正如預期的那樣,原始數據庫似乎沒有用Redis中的數據命中(如果它關閉,則沒有錯誤)。我認爲這是因爲fallback
未來在這種情況下沒有被使用,所以即使該方法被執行也不會完成。
如果fallback: Future[Seq[Thing]]
改爲調用 - 名稱(即fallback: => Future[Seq[Thing]]
),「getThingsFromDatabase」僅印刷在第一時間時,高速緩存爲空,如所預期的,因爲fallback
被稱爲僅在None()
條件和不執行作爲參數。
而後者則是預期的功能,會有原來,被呼叫的名稱版本之間的差異,如果沒有在getThingsFromDatabase
方法println
?如果Redis具有所需的數據,兩者似乎都可以滿足不去MySQL的需要,即使前者執行該方法,也不能實際完成Future。