make leaderboard caches easier on memory
This commit is contained in:
parent
4ff0ea41a0
commit
890f5b5195
|
@ -139,11 +139,11 @@ object User extends LilaController {
|
|||
antichess <- env.cached top10Perf PerfType.Antichess.key
|
||||
atomic <- env.cached top10Perf PerfType.Atomic.key
|
||||
horde <- env.cached top10Perf PerfType.Horde.key
|
||||
nbAllTime ← env.cached topNbGame nb map2 { (user: UserModel) =>
|
||||
user -> user.count.game
|
||||
}
|
||||
nbDay ← Env.game.cached activePlayerUidsDay nb flatMap { pairs =>
|
||||
UserRepo.byOrderedIds(pairs.map(_.userId)) map (_ zip pairs.map(_.nb))
|
||||
nbAllTime ← env.cached topNbGame nb
|
||||
nbDay ← Env.game.cached activePlayerUidsDay nb map {
|
||||
_ flatMap { pair =>
|
||||
env lightUser pair.userId map { UserModel.LightCount(_, pair.nb) }
|
||||
}
|
||||
}
|
||||
tourneyWinners ← Env.tournament.winners scheduled nb
|
||||
online ← env.cached topOnline 50
|
||||
|
@ -163,9 +163,15 @@ object User extends LilaController {
|
|||
nbDay = nbDay,
|
||||
nbAllTime = nbAllTime))),
|
||||
api = _ => fuccess {
|
||||
implicit val userWrites = play.api.libs.json.Writes[UserModel] { env.jsonView(_, true) }
|
||||
implicit val lightPerfWrites = play.api.libs.json.Writes[UserModel.LightPerf] { l =>
|
||||
Json.obj(
|
||||
"id" -> l.user.id,
|
||||
"username" -> l.user.name,
|
||||
"title" -> l.user.title,
|
||||
"perfs" -> Json.obj(
|
||||
l.perfKey -> Json.obj("rating" -> l.rating, "progress" -> l.progress)))
|
||||
}
|
||||
Ok(Json.obj(
|
||||
"online" -> online,
|
||||
"bullet" -> bullet,
|
||||
"blitz" -> blitz,
|
||||
"classical" -> classical,
|
||||
|
|
|
@ -16,7 +16,7 @@ import play.api.libs.json._
|
|||
|
||||
final class Preload(
|
||||
tv: Tv,
|
||||
leaderboard: Boolean => Fu[List[(User, PerfType)]],
|
||||
leaderboard: Boolean => Fu[List[User.LightPerf]],
|
||||
tourneyWinners: Int => Fu[List[Winner]],
|
||||
timelineEntries: String => Fu[List[Entry]],
|
||||
streamsOnAir: () => Fu[List[StreamOnAir]],
|
||||
|
@ -26,7 +26,7 @@ final class Preload(
|
|||
getPlayban: String => Fu[Option[TempBan]],
|
||||
lightUser: String => Option[LightUser]) {
|
||||
|
||||
private type Response = (JsObject, List[Entry], List[MiniForumPost], List[Tournament], List[Simul], Option[Game], List[(User, PerfType)], List[Winner], Option[lila.puzzle.DailyPuzzle], List[StreamOnAir], List[lila.blog.MiniPost], Option[TempBan], Option[Preload.CurrentGame], Int)
|
||||
private type Response = (JsObject, List[Entry], List[MiniForumPost], List[Tournament], List[Simul], Option[Game], List[User.LightPerf], List[Winner], Option[lila.puzzle.DailyPuzzle], List[StreamOnAir], List[lila.blog.MiniPost], Option[TempBan], Option[Preload.CurrentGame], Int)
|
||||
|
||||
def apply(
|
||||
posts: Fu[List[MiniForumPost]],
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@(data: play.api.libs.json.JsObject, userTimeline: List[lila.timeline.Entry], forumRecent: List[lila.forum.MiniForumPost], tours: List[Tournament], simuls: List[lila.simul.Simul], featured: Option[Game], leaderboard: List[(User, lila.rating.PerfType)], tournamentWinners: List[lila.tournament.Winner], puzzle: Option[lila.puzzle.DailyPuzzle], streams: List[lila.tv.StreamOnAir], lastPost: List[lila.blog.MiniPost], playban: Option[lila.playban.TempBan], currentGame: Option[lila.app.mashup.Preload.CurrentGame], nbRounds: Int)(implicit ctx: Context)
|
||||
@(data: play.api.libs.json.JsObject, userTimeline: List[lila.timeline.Entry], forumRecent: List[lila.forum.MiniForumPost], tours: List[Tournament], simuls: List[lila.simul.Simul], featured: Option[Game], leaderboard: List[User.LightPerf], tournamentWinners: List[lila.tournament.Winner], puzzle: Option[lila.puzzle.DailyPuzzle], streams: List[lila.tv.StreamOnAir], lastPost: List[lila.blog.MiniPost], playban: Option[lila.playban.TempBan], currentGame: Option[lila.app.mashup.Preload.CurrentGame], nbRounds: Int)(implicit ctx: Context)
|
||||
|
||||
@underchat = {
|
||||
<div id="featured_game">
|
||||
|
@ -140,15 +140,15 @@ description = trans.freeOnlineChessGamePlayChessNowInACleanInterfaceNoRegistrati
|
|||
<div class="undertable_inner scroll-shadow-hard">
|
||||
<table>
|
||||
<tbody>
|
||||
@leaderboard.map {
|
||||
case (u, pt) => {
|
||||
@leaderboard.map { l =>
|
||||
<tr>
|
||||
<td>@userLink(u)</td>
|
||||
<td>@showPerfRating(u, pt, klass = "title")</td>
|
||||
<td>@showProgress(u.perfs(pt).progress, withTitle = false)</td>
|
||||
<td>@lightUserLink(l.user)</td>
|
||||
@lila.rating.PerfType(l.perfKey).map { pt =>
|
||||
<td data-icon="@pt.iconChar">l.rating</td>
|
||||
}
|
||||
<td>@showProgress(l.progress, withTitle = false)</td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
|
|
@ -1,20 +1,18 @@
|
|||
@(tourneyWinners: List[lila.tournament.Winner], online: List[User], bullet: List[User], blitz: List[User], classical: List[User], chess960: List[User], kingOfTheHill: List[User], threeCheck: List[User], antichess: List[User], atomic: List[User], horde: List[User], nbDay: List[(User, Int)], nbAllTime: List[(User, Int)])(implicit ctx: Context)
|
||||
@(tourneyWinners: List[lila.tournament.Winner], online: List[User], bullet: List[User.LightPerf], blitz: List[User.LightPerf], classical: List[User.LightPerf], chess960: List[User.LightPerf], kingOfTheHill: List[User.LightPerf], threeCheck: List[User.LightPerf], antichess: List[User.LightPerf], atomic: List[User.LightPerf], horde: List[User.LightPerf], nbDay: List[User.LightCount], nbAllTime: List[User.LightCount])(implicit ctx: Context)
|
||||
|
||||
@import lila.rating.PerfType
|
||||
|
||||
@userTopPerf(users: List[User], perfType: PerfType) = {
|
||||
@userTopPerf(users: List[User.LightPerf], perfType: PerfType) = {
|
||||
<div class="user_top">
|
||||
<h2 class="text" data-icon="@perfType.iconChar">
|
||||
<a href="@routes.User.top200(perfType.key)">
|
||||
@perfType.name
|
||||
</a>
|
||||
<a href="@routes.User.top200(perfType.key)">@perfType.name</a>
|
||||
</h2>
|
||||
<table>
|
||||
<tbody>
|
||||
@users.map { u =>
|
||||
@users.map { l =>
|
||||
<tr>
|
||||
<td>@userLink(u)</td>
|
||||
<td>@u.perfs(perfType.key).map(_.intRating)</td>
|
||||
<td>@lightUserLink(l.user)</td>
|
||||
<td>@l.rating</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
|
@ -22,15 +20,15 @@
|
|||
</div>
|
||||
}
|
||||
|
||||
@userTopActive(users: List[(User, Int)], title: Any, icon: Option[Char] = None) = {
|
||||
@userTopActive(users: List[User.LightCount], title: Any, icon: Option[Char] = None) = {
|
||||
<div class="user_top">
|
||||
<h2 class="text"@icon.map { i => data-icon="@i" }>@title</h2>
|
||||
<table>
|
||||
<tbody>
|
||||
@users.map { u =>
|
||||
<tr>
|
||||
<td>@userLink(u._1)</td>
|
||||
<td title="@trans.gamesPlayed()">#@u._2.localize</td>
|
||||
<td>@lightUserLink(u.user)</td>
|
||||
<td title="@trans.gamesPlayed()">#@u.count.localize</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
|
|
|
@ -12,8 +12,8 @@ import lila.db.BSON._
|
|||
import lila.db.Implicits._
|
||||
import lila.memo.{ ExpireSetMemo, MongoCache }
|
||||
import lila.rating.{ Perf, PerfType }
|
||||
import User.LightPerf
|
||||
import tube.userTube
|
||||
import User.{ LightPerf, LightCount }
|
||||
|
||||
final class Cached(
|
||||
nbTtl: FiniteDuration,
|
||||
|
@ -30,13 +30,15 @@ final class Cached(
|
|||
|
||||
def countEnabled: Fu[Int] = countCache(true)
|
||||
|
||||
private implicit val userHandler = User.userBSONHandler
|
||||
private implicit val LightUserBSONHandler = reactivemongo.bson.Macros.handler[LightUser]
|
||||
private implicit val LightPerfBSONHandler = reactivemongo.bson.Macros.handler[LightPerf]
|
||||
private implicit val LightCountBSONHandler = reactivemongo.bson.Macros.handler[LightCount]
|
||||
|
||||
val top10Perf = mongoCache[Perf.Key, List[User]](
|
||||
val top10Perf = mongoCache[Perf.Key, List[LightPerf]](
|
||||
prefix = "user:top10:perf",
|
||||
f = (perf: Perf.Key) => UserRepo.topPerfSince(perf, oneWeekAgo, 10),
|
||||
f = (perf: Perf.Key) => UserRepo.topPerfSince(perf, oneWeekAgo, 10) map {
|
||||
_ flatMap (_ lightPerf perf)
|
||||
},
|
||||
timeToLive = 10 minutes)
|
||||
|
||||
val top200Perf = mongoCache[Perf.Key, List[User.LightPerf]](
|
||||
|
@ -46,26 +48,20 @@ final class Cached(
|
|||
},
|
||||
timeToLive = 10 minutes)
|
||||
|
||||
private case class UserPerf(user: User, perfKey: String)
|
||||
private implicit val UserPerfBSONHandler = reactivemongo.bson.Macros.handler[UserPerf]
|
||||
|
||||
private val topTodayCache = mongoCache.single[List[UserPerf]](
|
||||
private val topTodayCache = mongoCache.single[List[User.LightPerf]](
|
||||
prefix = "user:top:today",
|
||||
f = PerfType.leaderboardable.map { perf =>
|
||||
UserRepo.topPerfSince(perf.key, DateTime.now minusHours 12, 1) map2 { (u: User) =>
|
||||
UserPerf(u, perf.key)
|
||||
UserRepo.topPerfSince(perf.key, DateTime.now minusHours 12, 1).map {
|
||||
_.headOption flatMap (_ lightPerf perf.key)
|
||||
}
|
||||
}.sequenceFu map (_.flatten),
|
||||
}.sequenceFu.map(_.flatten),
|
||||
timeToLive = 9 minutes)
|
||||
|
||||
def topToday(x: Boolean): Fu[List[(User, PerfType)]] =
|
||||
topTodayCache(x) map2 { (up: UserPerf) =>
|
||||
(up.user, PerfType(up.perfKey) err s"No such perf ${up.perfKey}")
|
||||
}
|
||||
def topToday = topTodayCache.apply _
|
||||
|
||||
val topNbGame = mongoCache[Int, List[User]](
|
||||
val topNbGame = mongoCache[Int, List[User.LightCount]](
|
||||
prefix = "user:top:nbGame",
|
||||
f = UserRepo.topNbGame,
|
||||
f = nb => UserRepo topNbGame nb map { _ map (_.lightCount) },
|
||||
timeToLive = 34 minutes)
|
||||
|
||||
val topOnline = lila.memo.AsyncCache[Int, List[User]](
|
||||
|
|
|
@ -72,8 +72,10 @@ case class User(
|
|||
def lameOrTroll = lame || troll
|
||||
|
||||
def lightPerf(key: String) = perfs(key) map { perf =>
|
||||
User.LightPerf(light, perf.intRating, perf.progress)
|
||||
User.LightPerf(light, key, perf.intRating, perf.progress)
|
||||
}
|
||||
|
||||
def lightCount = User.LightCount(light, count.game)
|
||||
}
|
||||
|
||||
object User {
|
||||
|
@ -82,10 +84,8 @@ object User {
|
|||
|
||||
val anonymous = "Anonymous"
|
||||
|
||||
case class LightPerf(
|
||||
user: LightUser,
|
||||
rating: Int,
|
||||
progress: Int)
|
||||
case class LightPerf(user: LightUser, perfKey: String, rating: Int, progress: Int)
|
||||
case class LightCount(user: LightUser, count: Int)
|
||||
|
||||
case class Active(user: User)
|
||||
|
||||
|
|
Loading…
Reference in a new issue