scala - play-cache -- memorize an Future with expiration which depends on the value of future -
given following functions
val readv : string => future[v] val isexpired: v => boolean
how memorize result of readv
until isexpired
by using play cache(or else)
here how did:
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) }
this complicated ensure correctness
is there simpler solution this.
if it's possible change isexpired: v => boolean
timetolive: v => duration
, can use
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))
to control concurrency, actor model:
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 } } } }
using actors, it'd nice if had readv
provides result synchronously, since actor model provides concurrency (and control).
client-side, it's:
val futurev = lookupactor ? lookup.get(key) mapto[v]
Comments
Post a Comment