Playframework中的Futures上的Cache.getOrElse

kor*_*dge 5 caching scala playframework-2.0

在playframework中缓存未来结果的正确方法是什么.例如:

val userGravatar: Future[JsValue] = RemoteGravatarService.get(user.id, user.email)

object RemoveGravatarService {
  def get(userId: String, email: String): Future[JsValue] = {
    Cache.getOrElse("gravatar-for-$userId", 1.hour) {
      WS.url("gravatar.com/email=$email").get().asJson
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我们不想问(这个虚构的)"的Gravatar"每一次,因为它不会改变频率.但我们需要在本地使用som userGravatar信息.

在这里我们缓存未来本身,但实际上我们只想缓存未来的结果.有没有方便/正确的方法来玩这个?

Mic*_*jac 7

Play的API中没有一个方法可以处理Futures.您可以包装Play的缓存API来处理orElse它返回的情况Future.一般:

object FutureCache {

    def getOrElse[A](key: String, expiration: Int)(orElse: => Future[A])
      (implicit app: Application, ct: ClassTag[A], ec: ExecutionContext): Future[A] = {
        Cache.getAs[A](key).map(Future.successful).getOrElse {
            val value = orElse
            value onSuccess { case result => Cache.set(key, result, expiration) }
            value
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

用法:

FutureCache.getOrElse[JsValue]("gravatar-for-$userId", 3600) {
  WS.url("gravatar.com/email=$email").get().map(_.json)
}
Run Code Online (Sandbox Code Playgroud)

您还可以getOrElse为该用途创建重载Duration.