gpt4 book ai didi

scala - play-cache -- 存储一个过期的 Future,这取决于 future 的值

转载 作者:行者123 更新时间:2023-12-02 04:25:19 25 4
gpt4 key购买 nike

给定以下功能

val readV : String => Future[V]
val isExpired: V => Boolean

如何使用 Play 缓存(或其他东西)记住 readV 的结果,直到它过期

这是我的做法:

  def getCached(k: String) = Cache.getAs[Future[V]](k)
def getOrRefresh(k: String) = getCached(k).getOrElse {
this.synchronized {
getCached(k).getOrElse {
val vFut = readV(k)
Cache.set(k, vFut)
vFut
}
}
}
def get(k: String) = getOrRefresh(k).flatMap {
case v if !isExpired(v) => Future.successful(v)
case _ =>
Cache.remove(k)
getOrRefresh(k)
}

这个太复杂了,不能保证正确性

Is there any simpler solution to do this.

最佳答案

如果可以将 isExpired: V => Boolean 更改为 timeToLive: V => Duration,那么您可以使用

def refresh(k: String): Future[V] = readV(k) andThen {
case Success(v) => Cache.set(k, Future.successful(v), timeToLive(v))
}

def get(k: String): Future[V] = Cache.getOrElse(k)(refresh(k))

为了控制并发,我喜欢actor模型:

object Lookup {
case class Get(key: String)


class LookupActor extends Actor {
def receive = {
case Get(key) =>
Cache.get(key) match {
case Some(v) => sender ! v
case None => val v = Await.result(readV(k), timeout)
Cache.set(key, v, timeToLive(v))
sender ! v
}
}
}
}

使用 actor 时,如果我们有一个同步提供结果的 readV 就好了,因为 actor 模型提供了并发性(和控制)。

客户端,它是:

val futureV = lookupActor ? Lookup.Get(key) mapTo[V]

关于scala - play-cache -- 存储一个过期的 Future,这取决于 future 的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27498485/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com