replace spray caching with AsyncCache2 in many places
parent
c39f5d20b3
commit
1986cb3235
|
@ -40,7 +40,7 @@ object Account extends LilaController {
|
|||
relationEnv.api.countFollowing(me.id) zip
|
||||
Env.pref.api.getPref(me) zip
|
||||
lila.game.GameRepo.urgentGames(me) zip
|
||||
Env.challenge.api.countInFor(me.id) map {
|
||||
Env.challenge.api.countInFor.get(me.id) map {
|
||||
case ((((nbFollowers, nbFollowing), prefs), povs), nbChallenges) =>
|
||||
Env.current.bus.publish(lila.user.User.Active(me), 'userActive)
|
||||
Ok {
|
||||
|
|
|
@ -291,7 +291,7 @@ private[controllers] trait LilaController
|
|||
Env.user.lightUserApi preloadUser me
|
||||
getOnlineFriends(me) zip
|
||||
Env.team.api.nbRequests(me.id) zip
|
||||
Env.challenge.api.countInFor(me.id) zip
|
||||
Env.challenge.api.countInFor.get(me.id) zip
|
||||
Env.notifyModule.api.unreadCount(Notifies(me.id)).map(_.value)
|
||||
}
|
||||
else fuccess {
|
||||
|
|
|
@ -71,9 +71,9 @@ object Lobby extends LilaController {
|
|||
|
||||
private def renderCtx(implicit ctx: Context): Fu[Html] = Env.current.preloader(
|
||||
posts = Env.forum.recent(ctx.me, Env.team.cached.teamIds),
|
||||
tours = Env.tournament.cached promotable true,
|
||||
events = Env.event.api promotable true,
|
||||
simuls = Env.simul allCreatedFeaturable true
|
||||
tours = Env.tournament.cached.promotable.get,
|
||||
events = Env.event.api.promotable.get,
|
||||
simuls = Env.simul.allCreatedFeaturable.get
|
||||
) map (html.lobby.home.apply _).tupled
|
||||
|
||||
private def renderRequestKey(r: RequestKey): Fu[Html] = renderCtx {
|
||||
|
|
|
@ -30,7 +30,7 @@ object Simul extends LilaController {
|
|||
}
|
||||
|
||||
private def fetchSimuls =
|
||||
env.allCreated(true) zip env.repo.allStarted zip env.repo.allFinished(30)
|
||||
env.allCreated.get zip env.repo.allStarted zip env.repo.allFinished(30)
|
||||
|
||||
def show(id: String) = Open { implicit ctx =>
|
||||
env.repo find id flatMap {
|
||||
|
|
|
@ -67,7 +67,7 @@ object User extends LilaController {
|
|||
val max = 50
|
||||
negotiate(
|
||||
html = notFound,
|
||||
api = _ => env.cached top50Online true map { list =>
|
||||
api = _ => env.cached.top50Online.get map { list =>
|
||||
Ok(Json.toJson(list.take(getInt("nb").fold(10)(_ min max)).map(env.jsonView(_))))
|
||||
})
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ object User extends LilaController {
|
|||
// }
|
||||
// }
|
||||
tourneyWinners ← Env.tournament.winners.all.map(_.top)
|
||||
online ← env.cached top50Online true
|
||||
online ← env.cached.top50Online.get
|
||||
_ <- Env.user.lightUserApi preloadMany tourneyWinners.map(_.userId)
|
||||
res <- negotiate(
|
||||
html = fuccess(Ok(html.user.list(
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package lila.blog
|
||||
|
||||
import io.prismic._
|
||||
import lila.memo.AsyncCache
|
||||
import scala.concurrent.duration._
|
||||
|
||||
final class BlogApi(prismicUrl: String, collection: String) {
|
||||
final class BlogApi(
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
prismicUrl: String,
|
||||
collection: String) {
|
||||
|
||||
def recent(api: Api, ref: Option[String], nb: Int): Fu[Option[Response]] =
|
||||
api.forms(collection).ref(resolveRef(api)(ref) | api.master.ref)
|
||||
|
@ -38,12 +40,12 @@ final class BlogApi(prismicUrl: String, collection: String) {
|
|||
case _ => logger info message
|
||||
}
|
||||
|
||||
private val fetchPrismicApi = AsyncCache.single[Api](
|
||||
private val fetchPrismicApi = asyncCache.single[Api](
|
||||
name = "blogApi.fetchPrismicApi",
|
||||
f = Api.get(prismicUrl, cache = cache, logger = prismicLogger),
|
||||
timeToLive = 10 seconds)
|
||||
expireAfter = _.ExpireAfterWrite(15 seconds))
|
||||
|
||||
def prismicApi = fetchPrismicApi(true)
|
||||
def prismicApi = fetchPrismicApi.get
|
||||
}
|
||||
|
||||
object BlogApi {
|
||||
|
|
|
@ -7,6 +7,7 @@ import lila.common.PimpedConfig._
|
|||
final class Env(
|
||||
config: Config,
|
||||
scheduler: lila.common.Scheduler,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
notifyApi: lila.notify.NotifyApi)(implicit system: akka.actor.ActorSystem) {
|
||||
|
||||
private val PrismicApiUrl = config getString "prismic.api_url"
|
||||
|
@ -17,6 +18,7 @@ final class Env(
|
|||
|
||||
lazy val api = new BlogApi(
|
||||
prismicUrl = PrismicApiUrl,
|
||||
asyncCache = asyncCache,
|
||||
collection = PrismicCollection)
|
||||
|
||||
lazy val lastPostCache = new LastPostCache(api, LastPostCacheTtl, PrismicCollection)
|
||||
|
@ -38,6 +40,7 @@ object Env {
|
|||
lazy val current: Env = "blog" boot new Env(
|
||||
config = lila.common.PlayApp loadConfig "blog",
|
||||
scheduler = lila.common.PlayApp.scheduler,
|
||||
asyncCache = lila.memo.Env.current.asyncCache,
|
||||
notifyApi = lila.notify.Env.current.api)(
|
||||
lila.common.PlayApp.system)
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ package lila.challenge
|
|||
|
||||
import akka.actor._
|
||||
import org.joda.time.DateTime
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import lila.game.{ Game, Pov, GameRepo }
|
||||
import lila.hub.actorApi.map.Tell
|
||||
import lila.hub.actorApi.SendTo
|
||||
import lila.memo.AsyncCache
|
||||
import lila.user.{ User, UserRepo }
|
||||
|
||||
final class ChallengeApi(
|
||||
|
@ -17,6 +17,7 @@ final class ChallengeApi(
|
|||
maxPlaying: Int,
|
||||
socketHub: ActorRef,
|
||||
userRegister: ActorSelection,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
lilaBus: lila.common.Bus) {
|
||||
|
||||
import Challenge._
|
||||
|
@ -29,38 +30,40 @@ final class ChallengeApi(
|
|||
case true => fuccess(false)
|
||||
case false => {
|
||||
repo like c flatMap { _ ?? repo.cancel }
|
||||
} >> (repo insert c) >> uncacheAndNotify(c) >>- {
|
||||
} >> (repo insert c) >>- {
|
||||
uncacheAndNotify(c)
|
||||
lilaBus.publish(Event.Create(c), 'challenge)
|
||||
} inject true
|
||||
}
|
||||
|
||||
def byId = repo byId _
|
||||
|
||||
val countInFor = AsyncCache(
|
||||
val countInFor = asyncCache.clearable(
|
||||
name = "challenge.countInFor",
|
||||
f = repo.countCreatedByDestId,
|
||||
maxCapacity = 20000)
|
||||
expireAfter = _.ExpireAfterAccess(12 minutes))
|
||||
|
||||
def createdByChallengerId = repo createdByChallengerId _
|
||||
|
||||
def createdByDestId = repo createdByDestId _
|
||||
|
||||
def cancel(c: Challenge) = (repo cancel c) >> uncacheAndNotify(c)
|
||||
def cancel(c: Challenge) = (repo cancel c) >>- uncacheAndNotify(c)
|
||||
|
||||
private def offline(c: Challenge) = (repo offline c) >> uncacheAndNotify(c)
|
||||
private def offline(c: Challenge) = (repo offline c) >>- uncacheAndNotify(c)
|
||||
|
||||
private[challenge] def ping(id: Challenge.ID): Funit = repo statusById id flatMap {
|
||||
case Some(Status.Created) => repo setSeen id
|
||||
case Some(Status.Offline) => (repo setSeenAgain id) >> byId(id).flatMap { _ ?? uncacheAndNotify }
|
||||
case Some(Status.Offline) => (repo setSeenAgain id) >> byId(id).map { _ foreach uncacheAndNotify }
|
||||
case _ => fuccess(socketReload(id))
|
||||
}
|
||||
|
||||
def decline(c: Challenge) = (repo decline c) >> uncacheAndNotify(c)
|
||||
def decline(c: Challenge) = (repo decline c) >>- uncacheAndNotify(c)
|
||||
|
||||
def accept(c: Challenge, user: Option[User]): Fu[Option[Pov]] =
|
||||
joiner(c, user).flatMap {
|
||||
case None => fuccess(None)
|
||||
case Some(pov) => (repo accept c) >> uncacheAndNotify(c) >>- {
|
||||
case Some(pov) => (repo accept c) >>- {
|
||||
uncacheAndNotify(c)
|
||||
lilaBus.publish(Event.Accept(c, user.map(_.id)), 'challenge)
|
||||
} inject pov.some
|
||||
}
|
||||
|
@ -111,22 +114,20 @@ final class ChallengeApi(
|
|||
}
|
||||
|
||||
private def remove(c: Challenge) =
|
||||
repo.remove(c.id) >> uncacheAndNotify(c)
|
||||
repo.remove(c.id) >>- uncacheAndNotify(c)
|
||||
|
||||
private def uncacheAndNotify(c: Challenge) = {
|
||||
(c.destUserId ?? countInFor.remove) >>-
|
||||
(c.destUserId ?? notify) >>-
|
||||
(c.challengerUserId ?? notify) >>-
|
||||
socketReload(c.id)
|
||||
private def uncacheAndNotify(c: Challenge): Unit = {
|
||||
c.destUserId ?? countInFor.invalidate
|
||||
c.destUserId ?? notify
|
||||
c.challengerUserId ?? notify
|
||||
socketReload(c.id)
|
||||
}
|
||||
|
||||
private def socketReload(id: Challenge.ID) {
|
||||
private def socketReload(id: Challenge.ID): Unit =
|
||||
socketHub ! Tell(id, Socket.Reload)
|
||||
}
|
||||
|
||||
private def notify(userId: User.ID) {
|
||||
private def notify(userId: User.ID): Unit =
|
||||
allFor(userId) foreach { all =>
|
||||
userRegister ! SendTo(userId, lila.socket.Socket.makeMessage("challenges", jsonView(all)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ final class Env(
|
|||
isOnline: lila.user.User.ID => Boolean,
|
||||
hub: lila.hub.Env,
|
||||
db: lila.db.Env,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
scheduler: lila.common.Scheduler) {
|
||||
|
||||
private val settings = new {
|
||||
|
@ -58,6 +59,7 @@ final class Env(
|
|||
maxPlaying = MaxPlaying,
|
||||
socketHub = socketHub,
|
||||
userRegister = hub.actor.userRegister,
|
||||
asyncCache = asyncCache,
|
||||
lilaBus = system.lilaBus)
|
||||
|
||||
private lazy val repo = new ChallengeRepo(
|
||||
|
@ -82,5 +84,6 @@ object Env {
|
|||
lightUser = lila.user.Env.current.lightUserSync,
|
||||
isOnline = lila.user.Env.current.isOnline,
|
||||
db = lila.db.Env.current,
|
||||
asyncCache = lila.memo.Env.current.asyncCache,
|
||||
scheduler = lila.common.PlayApp.scheduler)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import org.joda.time.DateTime
|
|||
import scala.concurrent.duration._
|
||||
|
||||
import lila.db.dsl._
|
||||
import lila.memo.AsyncCache
|
||||
import lila.notify.{ Notification, NotifyApi }
|
||||
import lila.security.Granter
|
||||
import lila.user.{ User, UserRepo }
|
||||
|
@ -13,16 +12,17 @@ final class CoachApi(
|
|||
coachColl: Coll,
|
||||
reviewColl: Coll,
|
||||
photographer: Photographer,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
notifyApi: NotifyApi) {
|
||||
|
||||
import BsonHandlers._
|
||||
|
||||
private val cache = AsyncCache.single[List[Coach]](
|
||||
private val cache = asyncCache.single[List[Coach]](
|
||||
name = "coach.list",
|
||||
f = coachColl.find($empty).list[Coach](),
|
||||
timeToLive = 10 minutes)
|
||||
expireAfter = _.ExpireAfterWrite(30 minutes))
|
||||
|
||||
private def all = cache(true)
|
||||
private def all = cache.get
|
||||
|
||||
def byId(id: Coach.Id): Fu[Option[Coach]] = all.map(_.find(_.id == id))
|
||||
|
||||
|
@ -36,7 +36,7 @@ final class CoachApi(
|
|||
def findOrInit(user: User): Fu[Option[Coach.WithUser]] = Granter(_.Coach)(user) ?? {
|
||||
find(user) orElse {
|
||||
val c = Coach.WithUser(Coach make user, user)
|
||||
coachColl.insert(c.coach) >> cache.remove(true) inject c.some
|
||||
coachColl.insert(c.coach) >>- cache.refresh inject c.some
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,10 +59,10 @@ final class CoachApi(
|
|||
$id(c.coach.id),
|
||||
data(c.coach),
|
||||
upsert = true
|
||||
).void >> cache.clear
|
||||
).void >>- cache.refresh
|
||||
|
||||
def setNbReviews(id: Coach.Id, nb: Int): Funit =
|
||||
coachColl.update($id(id), $set("nbReviews" -> nb)).void >> cache.clear
|
||||
coachColl.update($id(id), $set("nbReviews" -> nb)).void >>- cache.refresh
|
||||
|
||||
private[coach] def toggleApproved(username: String, value: Boolean): Fu[String] =
|
||||
find(username) flatMap {
|
||||
|
@ -70,16 +70,16 @@ final class CoachApi(
|
|||
case Some(c) => coachColl.update(
|
||||
$id(c.coach.id),
|
||||
$set("approved" -> value)
|
||||
) >> cache.clear inject "Done!"
|
||||
) >>- cache.refresh inject "Done!"
|
||||
}
|
||||
|
||||
def uploadPicture(c: Coach.WithUser, picture: Photographer.Uploaded): Funit =
|
||||
photographer(c.coach.id, picture).flatMap { pic =>
|
||||
coachColl.update($id(c.coach.id), $set("picturePath" -> pic.path))
|
||||
} >> cache.clear
|
||||
coachColl.update($id(c.coach.id), $set("picturePath" -> pic.path)).void
|
||||
} >>- cache.refresh
|
||||
|
||||
def deletePicture(c: Coach.WithUser): Funit =
|
||||
coachColl.update($id(c.coach.id), $unset("picturePath")) >> cache.clear
|
||||
coachColl.update($id(c.coach.id), $unset("picturePath")).void >>- cache.refresh
|
||||
|
||||
private def withUser(user: User)(coach: Coach): Coach.WithUser =
|
||||
Coach.WithUser(coach, user)
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.typesafe.config.Config
|
|||
final class Env(
|
||||
config: Config,
|
||||
notifyApi: lila.notify.NotifyApi,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
db: lila.db.Env) {
|
||||
|
||||
private val CollectionCoach = config getString "collection.coach"
|
||||
|
@ -21,6 +22,7 @@ final class Env(
|
|||
coachColl = coachColl,
|
||||
reviewColl = reviewColl,
|
||||
photographer = photographer,
|
||||
asyncCache = asyncCache,
|
||||
notifyApi = notifyApi)
|
||||
|
||||
lazy val pager = new CoachPager(api)
|
||||
|
@ -38,5 +40,6 @@ object Env {
|
|||
lazy val current: Env = "coach" boot new Env(
|
||||
config = lila.common.PlayApp loadConfig "coach",
|
||||
notifyApi = lila.notify.Env.current.api,
|
||||
asyncCache = lila.memo.Env.current.asyncCache,
|
||||
db = lila.db.Env.current)
|
||||
}
|
||||
|
|
|
@ -6,13 +6,14 @@ import com.typesafe.config.Config
|
|||
final class Env(
|
||||
config: Config,
|
||||
db: lila.db.Env,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
system: ActorSystem) {
|
||||
|
||||
private val CollectionEvent = config getString "collection.event"
|
||||
|
||||
private lazy val eventColl = db(CollectionEvent)
|
||||
|
||||
lazy val api = new EventApi(coll = eventColl)
|
||||
lazy val api = new EventApi(coll = eventColl, asyncCache = asyncCache)
|
||||
}
|
||||
|
||||
object Env {
|
||||
|
@ -20,5 +21,6 @@ object Env {
|
|||
lazy val current = "event" boot new Env(
|
||||
config = lila.common.PlayApp loadConfig "event",
|
||||
db = lila.db.Env.current,
|
||||
asyncCache = lila.memo.Env.current.asyncCache,
|
||||
system = lila.common.PlayApp.system)
|
||||
}
|
||||
|
|
|
@ -6,13 +6,16 @@ import scala.concurrent.duration._
|
|||
import lila.db.dsl._
|
||||
import lila.memo._
|
||||
|
||||
final class EventApi(coll: Coll) {
|
||||
final class EventApi(
|
||||
coll: Coll,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder) {
|
||||
|
||||
import BsonHandlers._
|
||||
|
||||
val promotable = AsyncCache.single(
|
||||
val promotable = asyncCache.single(
|
||||
name = "event.promotable",
|
||||
fetchPromotable, timeToLive = 5 minutes)
|
||||
fetchPromotable,
|
||||
expireAfter = _.ExpireAfterWrite(5 minutes))
|
||||
|
||||
def fetchPromotable: Fu[List[Event]] = coll.find($doc(
|
||||
"enabled" -> true,
|
||||
|
@ -37,12 +40,12 @@ final class EventApi(coll: Coll) {
|
|||
}
|
||||
|
||||
def update(old: Event, data: EventForm.Data) =
|
||||
coll.update($id(old.id), data update old) >> promotable.clear
|
||||
coll.update($id(old.id), data update old) >>- promotable.refresh
|
||||
|
||||
def createForm = EventForm.form
|
||||
|
||||
def create(data: EventForm.Data, userId: String): Fu[Event] = {
|
||||
val event = data make userId
|
||||
coll.insert(event) >> promotable.clear inject event
|
||||
coll.insert(event) >>- promotable.refresh inject event
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,17 +3,18 @@ package lila.game
|
|||
import scala.concurrent.duration._
|
||||
|
||||
import lila.db.dsl._
|
||||
import lila.memo.{ AsyncCache, MongoCache, ExpireSetMemo }
|
||||
import lila.memo.{ MongoCache, ExpireSetMemo }
|
||||
import lila.user.User
|
||||
|
||||
final class Cached(
|
||||
coll: Coll,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
mongoCache: MongoCache.Builder) {
|
||||
|
||||
def nbImportedBy(userId: String): Fu[Int] = nbImportedCache(userId)
|
||||
def clearNbImportedByCache = nbImportedCache remove _
|
||||
|
||||
def nbPlaying(userId: String): Fu[Int] = countShortTtl(Query nowPlaying userId)
|
||||
def nbPlaying(userId: String): Fu[Int] = countShortTtl.get(Query nowPlaying userId)
|
||||
|
||||
def nbTotal: Fu[Int] = countCache($empty)
|
||||
|
||||
|
@ -23,10 +24,10 @@ final class Cached(
|
|||
|
||||
val isRematch = new ExpireSetMemo(3.hours)
|
||||
|
||||
private val countShortTtl = AsyncCache[Bdoc, Int](
|
||||
private val countShortTtl = asyncCache.multi[Bdoc, Int](
|
||||
name = "game.countShortTtl",
|
||||
f = coll.countSel,
|
||||
timeToLive = 5.seconds)
|
||||
expireAfter = _.ExpireAfterWrite(5.seconds))
|
||||
|
||||
private val nbImportedCache = mongoCache[User.ID, Int](
|
||||
prefix = "game:imported",
|
||||
|
|
|
@ -14,6 +14,7 @@ final class Env(
|
|||
getLightUser: lila.common.LightUser.GetterSync,
|
||||
appPath: String,
|
||||
isProd: Boolean,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
scheduler: lila.common.Scheduler) {
|
||||
|
||||
private val settings = new {
|
||||
|
@ -39,6 +40,7 @@ final class Env(
|
|||
|
||||
lazy val cached = new Cached(
|
||||
coll = gameColl,
|
||||
asyncCache = asyncCache,
|
||||
mongoCache = mongoCache)
|
||||
|
||||
lazy val paginator = new PaginatorBuilder(
|
||||
|
@ -94,5 +96,6 @@ object Env {
|
|||
getLightUser = lila.user.Env.current.lightUserSync,
|
||||
appPath = play.api.Play.current.path.getCanonicalPath,
|
||||
isProd = lila.common.PlayApp.isProd,
|
||||
asyncCache = lila.memo.Env.current.asyncCache,
|
||||
scheduler = lila.common.PlayApp.scheduler)
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ final class PublicChat(
|
|||
}
|
||||
|
||||
private def fetchVisibleSimuls: Fu[List[Simul]] = {
|
||||
simulEnv.allCreated(true) zip
|
||||
simulEnv.allCreated.get zip
|
||||
simulEnv.repo.allStarted zip
|
||||
simulEnv.repo.allFinished(3) map {
|
||||
case ((created, started), finished) =>
|
||||
|
|
|
@ -7,20 +7,21 @@ import akka.pattern.ask
|
|||
import org.joda.time.DateTime
|
||||
|
||||
import lila.db.dsl._
|
||||
import Puzzle.{BSONFields => F}
|
||||
import Puzzle.{ BSONFields => F }
|
||||
|
||||
private[puzzle] final class Daily(
|
||||
coll: Coll,
|
||||
renderer: ActorSelection,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
scheduler: Scheduler) {
|
||||
|
||||
private val cache =
|
||||
lila.memo.AsyncCache.single[Option[DailyPuzzle]](
|
||||
asyncCache.single[Option[DailyPuzzle]](
|
||||
name = "puzzle.daily",
|
||||
f = find,
|
||||
timeToLive = 10 minutes)
|
||||
expireAfter = _.ExpireAfterWrite(10 minutes))
|
||||
|
||||
def apply(): Fu[Option[DailyPuzzle]] = cache apply true
|
||||
def apply: Fu[Option[DailyPuzzle]] = cache.get
|
||||
|
||||
private def find: Fu[Option[DailyPuzzle]] = (findCurrent orElse findNew) recover {
|
||||
case e: Exception =>
|
||||
|
@ -28,9 +29,7 @@ private[puzzle] final class Daily(
|
|||
none
|
||||
} flatMap {
|
||||
case Some(puzzle) => makeDaily(puzzle)
|
||||
case None =>
|
||||
scheduler.scheduleOnce(10.seconds)(cache.clear)
|
||||
fuccess(none)
|
||||
case None => fuccess(none)
|
||||
}
|
||||
|
||||
private def makeDaily(puzzle: Puzzle): Fu[Option[DailyPuzzle]] = {
|
||||
|
|
|
@ -9,6 +9,7 @@ final class Env(
|
|||
config: Config,
|
||||
renderer: ActorSelection,
|
||||
lightUser: lila.common.LightUser.GetterSync,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
system: ActorSystem,
|
||||
lifecycle: play.api.inject.ApplicationLifecycle) {
|
||||
|
||||
|
@ -26,7 +27,7 @@ final class Env(
|
|||
|
||||
private val db = new lila.db.Env("puzzle", config getConfig "mongodb", lifecycle)
|
||||
|
||||
private lazy val gameJson = new GameJson(lightUser)
|
||||
private lazy val gameJson = new GameJson(asyncCache, lightUser)
|
||||
|
||||
lazy val jsonView = new JsonView(
|
||||
gameJson,
|
||||
|
@ -39,6 +40,7 @@ final class Env(
|
|||
voteColl = voteColl,
|
||||
headColl = headColl,
|
||||
puzzleIdMin = PuzzleIdMin,
|
||||
asyncCache = asyncCache,
|
||||
apiToken = ApiToken)
|
||||
|
||||
lazy val finisher = new Finisher(
|
||||
|
@ -57,6 +59,7 @@ final class Env(
|
|||
lazy val daily = new Daily(
|
||||
puzzleColl,
|
||||
renderer,
|
||||
asyncCache = asyncCache,
|
||||
system.scheduler
|
||||
).apply _
|
||||
|
||||
|
@ -81,6 +84,7 @@ object Env {
|
|||
config = lila.common.PlayApp loadConfig "puzzle",
|
||||
renderer = lila.hub.Env.current.actor.renderer,
|
||||
lightUser = lila.user.Env.current.lightUserSync,
|
||||
asyncCache = lila.memo.Env.current.asyncCache,
|
||||
system = lila.common.PlayApp.system,
|
||||
lifecycle = lila.common.PlayApp.lifecycle)
|
||||
}
|
||||
|
|
|
@ -1,22 +1,25 @@
|
|||
package lila.puzzle
|
||||
|
||||
import play.api.libs.json._
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import lila.common.PimpedJson._
|
||||
import lila.game.{ Game, GameRepo, PerfPicker }
|
||||
import lila.tree.Node.partitionTreeJsonWriter
|
||||
|
||||
private final class GameJson(
|
||||
lightUser: lila.common.LightUser.GetterSync) {
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
lightUser: lila.common.LightUser.GetterSync) {
|
||||
|
||||
case class CacheKey(gameId: Game.ID, plies: Int)
|
||||
|
||||
private val cache = lila.memo.AsyncCache[CacheKey, JsObject](
|
||||
private val cache = asyncCache.multi[CacheKey, JsObject](
|
||||
name = "puzzle.gameJson",
|
||||
f = generate,
|
||||
maxCapacity = 500)
|
||||
expireAfter = _.ExpireAfterAccess(1 hour),
|
||||
maxCapacity = 1024)
|
||||
|
||||
def apply(gameId: Game.ID, plies: Int): Fu[JsObject] = cache(CacheKey(gameId, plies))
|
||||
def apply(gameId: Game.ID, plies: Int): Fu[JsObject] = cache get CacheKey(gameId, plies)
|
||||
|
||||
def generate(ck: CacheKey): Fu[JsObject] = ck match {
|
||||
case CacheKey(gameId, plies) =>
|
||||
|
|
|
@ -15,6 +15,7 @@ private[puzzle] final class PuzzleApi(
|
|||
voteColl: Coll,
|
||||
headColl: Coll,
|
||||
puzzleIdMin: PuzzleId,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
apiToken: String) {
|
||||
|
||||
import Puzzle.puzzleBSONHandler
|
||||
|
@ -32,9 +33,10 @@ private[puzzle] final class PuzzleApi(
|
|||
|
||||
private def lastId: Fu[Int] = lila.db.Util findNextId puzzleColl map (_ - 1)
|
||||
|
||||
val cachedLastId = lila.memo.AsyncCache.single(
|
||||
val cachedLastId = asyncCache.single(
|
||||
name = "puzzle.lastId",
|
||||
lastId, timeToLive = 5 minutes)
|
||||
lastId,
|
||||
expireAfter = _.ExpireAfterWrite(20 minutes))
|
||||
|
||||
def importOne(json: JsValue, token: String): Fu[PuzzleId] =
|
||||
if (token != apiToken) fufail("Invalid API token")
|
||||
|
|
|
@ -55,7 +55,7 @@ private[puzzle] final class Selector(
|
|||
private def newPuzzleForUser(user: User): Fu[Option[Puzzle]] = {
|
||||
val rating = user.perfs.puzzle.intRating min 2300 max 900
|
||||
val step = toleranceStepFor(rating)
|
||||
(api.head.find(user) zip api.puzzle.cachedLastId(true)) flatMap {
|
||||
(api.head.find(user) zip api.puzzle.cachedLastId.get) flatMap {
|
||||
case (opHead, maxId) =>
|
||||
val lastId = opHead match {
|
||||
case Some(PuzzleHead(_, _, l)) if l < maxId - 500 => l
|
||||
|
|
|
@ -20,7 +20,8 @@ final class Env(
|
|||
hub: lila.hub.Env,
|
||||
lightUser: lila.common.LightUser.Getter,
|
||||
onGameStart: String => Unit,
|
||||
isOnline: String => Boolean) {
|
||||
isOnline: String => Boolean,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder) {
|
||||
|
||||
private val settings = new {
|
||||
val CollectionSimul = config getString "collection.simul"
|
||||
|
@ -47,7 +48,8 @@ final class Env(
|
|||
userRegister = hub.actor.userRegister,
|
||||
lobby = hub.socket.lobby,
|
||||
onGameStart = onGameStart,
|
||||
sequencers = sequencerMap)
|
||||
sequencers = sequencerMap,
|
||||
asyncCache = asyncCache)
|
||||
|
||||
lazy val forms = new DataForm
|
||||
|
||||
|
@ -80,7 +82,8 @@ final class Env(
|
|||
case move: lila.hub.actorApi.round.MoveEvent =>
|
||||
move.simulId foreach { simulId =>
|
||||
move.opponentUserId foreach { opId =>
|
||||
hub.actor.userRegister ! lila.hub.actorApi.SendTo(opId,
|
||||
hub.actor.userRegister ! lila.hub.actorApi.SendTo(
|
||||
opId,
|
||||
lila.socket.Socket.makeMessage("simulPlayerMove", move.gameId))
|
||||
}
|
||||
}
|
||||
|
@ -89,13 +92,15 @@ final class Env(
|
|||
|
||||
def isHosting(userId: String): Fu[Boolean] = api.currentHostIds map (_ contains userId)
|
||||
|
||||
val allCreated = lila.memo.AsyncCache.single(
|
||||
val allCreated = asyncCache.single(
|
||||
name = "simul.allCreated",
|
||||
repo.allCreated, timeToLive = CreatedCacheTtl)
|
||||
repo.allCreated,
|
||||
expireAfter = _.ExpireAfterWrite(CreatedCacheTtl))
|
||||
|
||||
val allCreatedFeaturable = lila.memo.AsyncCache.single(
|
||||
val allCreatedFeaturable = asyncCache.single(
|
||||
name = "simul.allCreatedFeaturable",
|
||||
repo.allCreatedFeaturable, timeToLive = CreatedCacheTtl)
|
||||
repo.allCreatedFeaturable,
|
||||
expireAfter = _.ExpireAfterWrite(CreatedCacheTtl))
|
||||
|
||||
def version(tourId: String): Fu[Int] =
|
||||
socketHub ? Ask(tourId, GetVersion) mapTo manifest[Int]
|
||||
|
@ -121,5 +126,6 @@ object Env {
|
|||
hub = lila.hub.Env.current,
|
||||
lightUser = lila.user.Env.current.lightUser,
|
||||
onGameStart = lila.game.Env.current.onStart,
|
||||
isOnline = lila.user.Env.current.isOnline)
|
||||
isOnline = lila.user.Env.current.isOnline,
|
||||
asyncCache = lila.memo.Env.current.asyncCache)
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ import lila.game.{ Game, GameRepo }
|
|||
import lila.hub.actorApi.lobby.ReloadSimuls
|
||||
import lila.hub.actorApi.map.Tell
|
||||
import lila.hub.actorApi.timeline.{ Propagate, SimulCreate, SimulJoin }
|
||||
import lila.memo.AsyncCache
|
||||
import lila.socket.actorApi.SendToFlag
|
||||
import lila.user.{ User, UserRepo }
|
||||
import makeTimeout.short
|
||||
|
@ -26,14 +25,15 @@ private[simul] final class SimulApi(
|
|||
timeline: ActorSelection,
|
||||
userRegister: ActorSelection,
|
||||
lobby: ActorSelection,
|
||||
repo: SimulRepo) {
|
||||
repo: SimulRepo,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder) {
|
||||
|
||||
def currentHostIds: Fu[Set[String]] = currentHostIdsCache apply true
|
||||
def currentHostIds: Fu[Set[String]] = currentHostIdsCache.get
|
||||
|
||||
private val currentHostIdsCache = AsyncCache.single[Set[String]](
|
||||
private val currentHostIdsCache = asyncCache.single[Set[String]](
|
||||
name = "simul.currentHostIds",
|
||||
f = repo.allStarted map (_ map (_.hostId) toSet),
|
||||
timeToLive = 10 minutes)
|
||||
expireAfter = _.ExpireAfterAccess(10 minutes))
|
||||
|
||||
def create(setup: SimulSetup, me: User): Fu[Simul] = {
|
||||
val simul = Simul.make(
|
||||
|
@ -90,7 +90,7 @@ private[simul] final class SimulApi(
|
|||
}
|
||||
}
|
||||
} flatMap update
|
||||
} >> currentHostIdsCache.remove(true)
|
||||
} >>- currentHostIdsCache.refresh
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +122,8 @@ private[simul] final class SimulApi(
|
|||
game.id,
|
||||
_.finish(game.status, game.winnerUserId, game.turns)
|
||||
)
|
||||
update(simul2) >> currentHostIdsCache.remove(true) >>- {
|
||||
update(simul2) >>- {
|
||||
currentHostIdsCache.refresh
|
||||
if (simul2.isFinished) userRegister ! lila.hub.actorApi.SendTo(
|
||||
simul2.hostId,
|
||||
lila.socket.Socket.makeMessage("simulEnd", Json.obj(
|
||||
|
|
|
@ -5,6 +5,7 @@ import scala.concurrent.duration._
|
|||
import lila.memo._
|
||||
|
||||
private[tournament] final class Cached(
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
createdTtl: FiniteDuration,
|
||||
rankingTtl: FiniteDuration)(implicit system: akka.actor.ActorSystem) {
|
||||
|
||||
|
@ -18,13 +19,13 @@ private[tournament] final class Cached(
|
|||
|
||||
def name(id: String): Option[String] = nameCache sync id
|
||||
|
||||
val promotable = AsyncCache.single(
|
||||
val promotable = asyncCache.single(
|
||||
name = "tournament.promotable",
|
||||
TournamentRepo.promotable,
|
||||
timeToLive = createdTtl)
|
||||
expireAfter = _.ExpireAfterWrite(createdTtl))
|
||||
|
||||
def findNext(tour: Tournament): Fu[Option[Tournament]] = tour.perfType ?? { pt =>
|
||||
promotable(true) map { tours =>
|
||||
promotable.get map { tours =>
|
||||
tours
|
||||
.filter(_.perfType contains pt)
|
||||
.filter(_.isScheduled)
|
||||
|
@ -34,18 +35,18 @@ private[tournament] final class Cached(
|
|||
}
|
||||
|
||||
def ranking(tour: Tournament): Fu[Ranking] =
|
||||
if (tour.isFinished) finishedRanking(tour.id)
|
||||
else ongoingRanking(tour.id)
|
||||
if (tour.isFinished) finishedRanking get tour.id
|
||||
else ongoingRanking get tour.id
|
||||
|
||||
// only applies to ongoing tournaments
|
||||
private val ongoingRanking = AsyncCache[String, Ranking](
|
||||
private val ongoingRanking = asyncCache.multi[String, Ranking](
|
||||
name = "tournament.ongoingRanking",
|
||||
f = PlayerRepo.computeRanking,
|
||||
timeToLive = 3.seconds)
|
||||
expireAfter = _.ExpireAfterWrite(3.seconds))
|
||||
|
||||
// only applies to finished tournaments
|
||||
private val finishedRanking = AsyncCache[String, Ranking](
|
||||
private val finishedRanking = asyncCache.multi[String, Ranking](
|
||||
name = "tournament.finishedRanking",
|
||||
f = PlayerRepo.computeRanking,
|
||||
timeToLive = rankingTtl)
|
||||
expireAfter = _.ExpireAfterAccess(rankingTtl))
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ final class Env(
|
|||
system: ActorSystem,
|
||||
db: lila.db.Env,
|
||||
mongoCache: lila.memo.MongoCache.Builder,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
flood: lila.security.Flood,
|
||||
hub: lila.hub.Env,
|
||||
roundMap: ActorRef,
|
||||
|
@ -55,6 +56,7 @@ final class Env(
|
|||
lazy val forms = new DataForm
|
||||
|
||||
lazy val cached = new Cached(
|
||||
asyncCache = asyncCache,
|
||||
createdTtl = CreatedCacheTtl,
|
||||
rankingTtl = RankingCacheTtl)(system)
|
||||
|
||||
|
@ -86,6 +88,7 @@ final class Env(
|
|||
verify = verify,
|
||||
indexLeaderboard = leaderboardIndexer.indexOne _,
|
||||
roundMap = roundMap,
|
||||
asyncCache = asyncCache,
|
||||
standingChannel = standingChannel)
|
||||
|
||||
lazy val crudApi = new crud.CrudApi
|
||||
|
@ -182,6 +185,7 @@ object Env {
|
|||
system = lila.common.PlayApp.system,
|
||||
db = lila.db.Env.current,
|
||||
mongoCache = lila.memo.Env.current.mongoCache,
|
||||
asyncCache = lila.memo.Env.current.asyncCache,
|
||||
flood = lila.security.Env.current.flood,
|
||||
hub = lila.hub.Env.current,
|
||||
roundMap = lila.round.Env.current.roundMap,
|
||||
|
|
|
@ -35,6 +35,7 @@ final class TournamentApi(
|
|||
trophyApi: lila.user.TrophyApi,
|
||||
verify: Condition.Verify,
|
||||
indexLeaderboard: Tournament => Funit,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
standingChannel: ActorRef) {
|
||||
|
||||
def createTournament(setup: TournamentSetup, me: User): Fu[Tournament] = {
|
||||
|
@ -315,15 +316,15 @@ final class TournamentApi(
|
|||
}
|
||||
}
|
||||
|
||||
private val miniStandingCache = lila.memo.AsyncCache[String, List[RankedPlayer]](
|
||||
private val miniStandingCache = asyncCache.multi[String, List[RankedPlayer]](
|
||||
name = "tournament.miniStanding",
|
||||
id => PlayerRepo.bestByTourWithRank(id, 30),
|
||||
timeToLive = 3 second)
|
||||
expireAfter = _.ExpireAfterWrite(3 second))
|
||||
|
||||
def miniStanding(tourId: String, withStanding: Boolean): Fu[Option[MiniStanding]] =
|
||||
TournamentRepo byId tourId flatMap {
|
||||
_ ?? { tour =>
|
||||
if (withStanding) miniStandingCache(tour.id) map { rps =>
|
||||
if (withStanding) miniStandingCache get tour.id map { rps =>
|
||||
MiniStanding(tour, rps.some).some
|
||||
}
|
||||
else fuccess(MiniStanding(tour, none).some)
|
||||
|
|
|
@ -7,15 +7,15 @@ import reactivemongo.bson._
|
|||
|
||||
import lila.common.LightUser
|
||||
import lila.db.dsl._
|
||||
import lila.memo.{ ExpireSetMemo, MongoCache }
|
||||
import lila.rating.{ Perf, PerfType }
|
||||
import User.{ LightPerf, LightCount }
|
||||
|
||||
final class Cached(
|
||||
userColl: Coll,
|
||||
nbTtl: FiniteDuration,
|
||||
onlineUserIdMemo: ExpireSetMemo,
|
||||
mongoCache: MongoCache.Builder,
|
||||
onlineUserIdMemo: lila.memo.ExpireSetMemo,
|
||||
mongoCache: lila.memo.MongoCache.Builder,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
rankingApi: RankingApi) {
|
||||
|
||||
private def oneWeekAgo = DateTime.now minusWeeks 1
|
||||
|
@ -77,10 +77,10 @@ final class Cached(
|
|||
timeToLive = 34 minutes,
|
||||
keyToString = _.toString)
|
||||
|
||||
val top50Online = lila.memo.AsyncCache.single[List[User]](
|
||||
val top50Online = asyncCache.single[List[User]](
|
||||
name = "user.top50online",
|
||||
f = UserRepo.byIdsSortRating(onlineUserIdMemo.keys, 50),
|
||||
timeToLive = 10 seconds)
|
||||
expireAfter = _.ExpireAfterWrite(10 seconds))
|
||||
|
||||
object ranking {
|
||||
|
||||
|
|
|
@ -4,12 +4,12 @@ import akka.actor._
|
|||
import com.typesafe.config.Config
|
||||
|
||||
import lila.common.PimpedConfig._
|
||||
import lila.memo.{ ExpireSetMemo, MongoCache }
|
||||
|
||||
final class Env(
|
||||
config: Config,
|
||||
db: lila.db.Env,
|
||||
mongoCache: MongoCache.Builder,
|
||||
mongoCache: lila.memo.MongoCache.Builder,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
scheduler: lila.common.Scheduler,
|
||||
timeline: ActorSelection,
|
||||
system: ActorSystem) {
|
||||
|
@ -29,13 +29,13 @@ final class Env(
|
|||
|
||||
lazy val lightUserApi = new LightUserApi(userColl)(system)
|
||||
|
||||
lazy val onlineUserIdMemo = new ExpireSetMemo(ttl = OnlineTtl)
|
||||
lazy val onlineUserIdMemo = new lila.memo.ExpireSetMemo(ttl = OnlineTtl)
|
||||
|
||||
lazy val noteApi = new NoteApi(db(CollectionNote), timeline, system.lilaBus)
|
||||
|
||||
lazy val trophyApi = new TrophyApi(db(CollectionTrophy))
|
||||
|
||||
lazy val rankingApi = new RankingApi(db(CollectionRanking), mongoCache, lightUser)
|
||||
lazy val rankingApi = new RankingApi(db(CollectionRanking), mongoCache, asyncCache, lightUser)
|
||||
|
||||
lazy val jsonView = new JsonView(isOnline)
|
||||
|
||||
|
@ -80,6 +80,7 @@ final class Env(
|
|||
nbTtl = CachedNbTtl,
|
||||
onlineUserIdMemo = onlineUserIdMemo,
|
||||
mongoCache = mongoCache,
|
||||
asyncCache = asyncCache,
|
||||
rankingApi = rankingApi)
|
||||
}
|
||||
|
||||
|
@ -89,6 +90,7 @@ object Env {
|
|||
config = lila.common.PlayApp loadConfig "user",
|
||||
db = lila.db.Env.current,
|
||||
mongoCache = lila.memo.Env.current.mongoCache,
|
||||
asyncCache = lila.memo.Env.current.asyncCache,
|
||||
scheduler = lila.common.PlayApp.scheduler,
|
||||
timeline = lila.hub.Env.current.actor.timeline,
|
||||
system = lila.common.PlayApp.system)
|
||||
|
|
|
@ -7,12 +7,12 @@ import reactivemongo.bson._
|
|||
import scala.concurrent.duration._
|
||||
|
||||
import lila.db.dsl._
|
||||
import lila.memo.{ AsyncCache, MongoCache }
|
||||
import lila.rating.{ Perf, PerfType }
|
||||
|
||||
final class RankingApi(
|
||||
coll: Coll,
|
||||
mongoCache: MongoCache.Builder,
|
||||
mongoCache: lila.memo.MongoCache.Builder,
|
||||
asyncCache: lila.memo.AsyncCache2.Builder,
|
||||
lightUser: lila.common.LightUser.Getter) {
|
||||
|
||||
import RankingApi._
|
||||
|
@ -72,13 +72,13 @@ final class RankingApi(
|
|||
|
||||
def of(userId: User.ID): Fu[Map[Perf.Key, Int]] =
|
||||
lila.common.Future.traverseSequentially(PerfType.leaderboardable) { perf =>
|
||||
cache(perf.id) map { _ get userId map (perf.key -> _) }
|
||||
cache.get(perf.id) map { _ get userId map (perf.key -> _) }
|
||||
} map (_.flatten.toMap)
|
||||
|
||||
private val cache = AsyncCache[Perf.ID, Map[User.ID, Rank]](
|
||||
private val cache = asyncCache.multi[Perf.ID, Map[User.ID, Rank]](
|
||||
name = "rankingApi.weeklyStableRanking",
|
||||
f = compute,
|
||||
timeToLive = 15 minutes,
|
||||
expireAfter = _.ExpireAfterWrite(15 minutes),
|
||||
resultTimeout = 10 seconds)
|
||||
|
||||
private def compute(perfId: Perf.ID): Fu[Map[User.ID, Rank]] =
|
||||
|
|
Loading…
Reference in New Issue