stop caching the rating chart in the DB - for #7729

pull/7932/head
Thibault Duplessis 2021-01-15 16:06:04 +01:00
parent a301144ed4
commit 350d7bb57c
1 changed files with 43 additions and 45 deletions

View File

@ -1,74 +1,72 @@
package lila.history
import play.api.libs.json._
import scala.concurrent.duration._
import play.api.libs.json._
import lila.rating.PerfType
import lila.user.User
import lila.user.{ User, UserRepo }
import org.joda.time.DateTime
final class RatingChartApi(
historyApi: HistoryApi,
mongoCache: lila.memo.MongoCache.Api
userRepo: UserRepo,
cacheApi: lila.memo.CacheApi
)(implicit ec: scala.concurrent.ExecutionContext) {
def apply(user: User): Fu[Option[String]] =
cache.get(user) dmap { chart =>
cache.get(user.id) dmap { chart =>
chart.nonEmpty option chart
}
def singlePerf(user: User, perfType: PerfType): Fu[JsArray] =
historyApi.ratingsMap(user, perfType) map {
ratingsMapToJson(user, _)
ratingsMapToJson(user.id, user.createdAt, _)
} map JsArray.apply
private val cache = mongoCache[User, String](
1024,
"history:rating",
60 minutes,
_.id
) { loader =>
private val cache = cacheApi[User.ID, String](4096, "history.rating") {
_.expireAfterAccess(10 minutes)
.maximumSize(2048)
.buildAsyncFuture {
loader { user =>
build(user) dmap (~_)
}
.maximumSize(4096)
.buildAsyncFuture { userId =>
build(userId).dmap(~_)
}
}
private def ratingsMapToJson(user: User, ratingsMap: RatingsMap) =
private def ratingsMapToJson(userId: User.ID, createdAt: DateTime, ratingsMap: RatingsMap) =
ratingsMap.map { case (days, rating) =>
val date = user.createdAt plusDays days
val date = createdAt plusDays days
Json.arr(date.getYear, date.getMonthOfYear - 1, date.getDayOfMonth, rating)
}
private def build(user: User): Fu[Option[String]] =
historyApi get user.id map2 { (history: History) =>
lila.common.String.html.safeJsonValue {
Json.toJson {
import lila.rating.PerfType._
List(
Bullet,
Blitz,
Rapid,
Classical,
Correspondence,
Chess960,
KingOfTheHill,
ThreeCheck,
Antichess,
Atomic,
Horde,
RacingKings,
Crazyhouse,
Puzzle,
UltraBullet
) map { pt =>
Json.obj(
"name" -> pt.trans(lila.i18n.defaultLang),
"points" -> ratingsMapToJson(user, history(pt))
)
private def build(userId: User.ID): Fu[Option[String]] =
userRepo.createdAtById(userId) flatMap {
_ ?? { createdAt =>
historyApi get userId map2 { (history: History) =>
lila.common.String.html.safeJsonValue {
Json.toJson {
import lila.rating.PerfType._
List(
Bullet,
Blitz,
Rapid,
Classical,
Correspondence,
Chess960,
KingOfTheHill,
ThreeCheck,
Antichess,
Atomic,
Horde,
RacingKings,
Crazyhouse,
Puzzle,
UltraBullet
) map { pt =>
Json.obj(
"name" -> pt.trans(lila.i18n.defaultLang),
"points" -> ratingsMapToJson(userId, createdAt, history(pt))
)
}
}
}
}
}