From 35bee2ad42b13a62ec80bb653f5b0064fb3b707b Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Thu, 26 Jan 2017 22:04:22 +0100 Subject: [PATCH] expiration strategies for single async cache --- app/controllers/Prismic.scala | 5 ++- modules/memo/src/main/AsyncCache2.scala | 26 ------------- modules/memo/src/main/AsyncCache2Single.scala | 37 +++++++++++++++++++ 3 files changed, 40 insertions(+), 28 deletions(-) create mode 100644 modules/memo/src/main/AsyncCache2Single.scala diff --git a/app/controllers/Prismic.scala b/app/controllers/Prismic.scala index 150d83cd80..0cb1290cf1 100644 --- a/app/controllers/Prismic.scala +++ b/app/controllers/Prismic.scala @@ -2,6 +2,7 @@ package controllers import scala.concurrent.duration._ +import lila.memo.AsyncCache2Single import io.prismic.Fragment.DocumentLink import io.prismic.{ Api => PrismicApi, _ } import lila.app._ @@ -16,10 +17,10 @@ object Prismic { case _ => logger info message } - private val prismicApiCache = lila.memo.AsyncCache2Single[PrismicApi]( + private val prismicApiCache = AsyncCache2Single[PrismicApi]( name = "prismic.fetchPrismicApi", f = PrismicApi.get(Env.api.PrismicApiUrl, logger = prismicLogger), - timeToLive = 1 minute)(Env.current.system) + expireAfter = AsyncCache2Single.ExpireAfterWrite(1 minute))(Env.current.system) def prismicApi = prismicApiCache.get diff --git a/modules/memo/src/main/AsyncCache2.scala b/modules/memo/src/main/AsyncCache2.scala index c5dc3ff783..e4a8a9d6f1 100644 --- a/modules/memo/src/main/AsyncCache2.scala +++ b/modules/memo/src/main/AsyncCache2.scala @@ -36,29 +36,3 @@ object AsyncCache2 { case class ExpireAfterAccess(duration: FiniteDuration) extends ExpireAfter case class ExpireAfterWrite(duration: FiniteDuration) extends ExpireAfter } - -final class AsyncCache2Single[V] private (cache: AsyncLoadingCache[Unit, V], f: Unit => Fu[V]) { - - def get: Fu[V] = cache.get(()) - - def refresh: Unit = cache.put((), f(())) -} - -object AsyncCache2Single { - - def apply[V]( - name: String, - f: => Fu[V], - timeToLive: FiniteDuration, - resultTimeout: FiniteDuration = 5 seconds)(implicit system: ActorSystem) = { - val safeF = (_: Unit) => f.withTimeout( - duration = resultTimeout, - error = lila.common.LilaException(s"AsyncCache $name single timed out after $resultTimeout")) - new AsyncCache2Single[V]( - cache = Scaffeine() - .expireAfterWrite(timeToLive) - .maximumSize(1) - .buildAsyncFuture(safeF), - safeF) - } -} diff --git a/modules/memo/src/main/AsyncCache2Single.scala b/modules/memo/src/main/AsyncCache2Single.scala new file mode 100644 index 0000000000..679bbae3ba --- /dev/null +++ b/modules/memo/src/main/AsyncCache2Single.scala @@ -0,0 +1,37 @@ +package lila.memo + +import akka.actor.ActorSystem +import com.github.blemale.scaffeine.{ AsyncLoadingCache, Scaffeine } +import scala.concurrent.duration._ + +final class AsyncCache2Single[V] private (cache: AsyncLoadingCache[Unit, V], f: Unit => Fu[V]) { + + def get: Fu[V] = cache.get(()) + + def refresh: Unit = cache.put((), f(())) +} + +object AsyncCache2Single { + + def apply[V]( + name: String, + f: => Fu[V], + expireAfter: ExpireAfter, + resultTimeout: FiniteDuration = 5 seconds)(implicit system: ActorSystem) = { + val safeF = (_: Unit) => f.withTimeout( + duration = resultTimeout, + error = lila.common.LilaException(s"AsyncCache $name single timed out after $resultTimeout")) + val b1 = Scaffeine().maximumSize(1) + val b2 = expireAfter match { + case ExpireAfterAccess(duration) => b1 expireAfterAccess duration + case ExpireAfterWrite(duration) => b1 expireAfterWrite duration + } + new AsyncCache2Single[V]( + cache = b2.buildAsyncFuture(safeF), + safeF) + } + + sealed trait ExpireAfter + case class ExpireAfterAccess(duration: FiniteDuration) extends ExpireAfter + case class ExpireAfterWrite(duration: FiniteDuration) extends ExpireAfter +}