From 8c0fce29a819ecd9f53c6582a9745ba457b3ae43 Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Tue, 4 Jun 2013 12:05:41 +0200 Subject: [PATCH] update user ranking every 10 minutes --- app/Env.scala | 3 ++- app/mashup/UserInfo.scala | 19 ++++++++----------- modules/memo/src/main/AsyncCache.scala | 6 ++++++ modules/user/src/main/Env.scala | 3 +++ modules/user/src/main/Ranking.scala | 24 ++++++++++++++++++++++++ todo | 3 +++ 6 files changed, 46 insertions(+), 12 deletions(-) create mode 100644 modules/user/src/main/Ranking.scala diff --git a/app/Env.scala b/app/Env.scala index 453f00319b..c3b49496c8 100644 --- a/app/Env.scala +++ b/app/Env.scala @@ -29,7 +29,8 @@ final class Env( bookmarkApi = Env.bookmark.api, eloCalculator = Env.round.eloCalculator, relationApi = Env.relation.api, - postApi = Env.forum.postApi) _ + postApi = Env.forum.postApi, + getRank = Env.user.ranking.get) _ system.actorOf(Props(new actor.Renderer), name = RendererName) diff --git a/app/mashup/UserInfo.scala b/app/mashup/UserInfo.scala index 68ab7c8a8a..25fbb5b1e5 100644 --- a/app/mashup/UserInfo.scala +++ b/app/mashup/UserInfo.scala @@ -2,11 +2,11 @@ package lila.app package mashup import chess.{ EloCalculator, Color } -import lila.game.{ GameRepo, Game } -import lila.user.{ User, UserRepo, Context, EloChart } import lila.bookmark.BookmarkApi -import lila.relation.RelationApi import lila.forum.PostApi +import lila.game.{ GameRepo, Game } +import lila.relation.RelationApi +import lila.user.{ User, UserRepo, Context, EloChart } case class UserInfo( user: User, @@ -27,18 +27,15 @@ case class UserInfo( object UserInfo { - private val rankMinElo = 1800 - def apply( countUsers: () ⇒ Fu[Int], bookmarkApi: BookmarkApi, eloCalculator: EloCalculator, relationApi: RelationApi, - postApi: PostApi)(user: User, ctx: Context): Fu[UserInfo] = - ((user.elo >= rankMinElo) ?? { - UserRepo rank user flatMap { rank ⇒ - countUsers() map { nbUsers ⇒ (rank -> nbUsers).some } - } + postApi: PostApi, + getRank: String ⇒ Fu[Option[Int]])(user: User, ctx: Context): Fu[UserInfo] = + (getRank(user.id) flatMap { + _ ?? { rank ⇒ countUsers() map { nb ⇒ (rank -> nb).some } } }) zip ((ctx is user) ?? { GameRepo count (_ notFinished user.id) map (_.some) @@ -49,7 +46,7 @@ object UserInfo { (bookmarkApi countByUser user) zip EloChart(user) zip relationApi.nbFollowing(user.id) zip - relationApi.nbFollowers(user.id) zip + relationApi.nbFollowers(user.id) zip postApi.nbByUser(user.id) map { case (((((((rank, nbPlaying), nbWithMe), nbBookmark), eloChart), nbFollowing), nbFollowers), nbPosts) ⇒ new UserInfo( user = user, diff --git a/modules/memo/src/main/AsyncCache.scala b/modules/memo/src/main/AsyncCache.scala index 6e20fd87d9..b077d2548d 100644 --- a/modules/memo/src/main/AsyncCache.scala +++ b/modules/memo/src/main/AsyncCache.scala @@ -25,4 +25,10 @@ object AsyncCache { timeToIdle: Duration = Duration.Zero) = new AsyncCache( cache = LruCache(maxCapacity, initialCapacity, timeToLive, timeToIdle), f = f) + + def single[V]( + f: ⇒ Fu[V], + timeToLive: Duration = Duration.Zero) = new AsyncCache[Boolean, V]( + cache = LruCache(timeToLive = timeToLive), + f = _ ⇒ f) } diff --git a/modules/user/src/main/Env.scala b/modules/user/src/main/Env.scala index 98e16444a0..acfaa84cf7 100644 --- a/modules/user/src/main/Env.scala +++ b/modules/user/src/main/Env.scala @@ -17,6 +17,7 @@ final class Env( val EloUpdaterFloor = config getInt "elo_updater.floor" val CachedNbTtl = config duration "cached.nb.ttl" val OnlineTtl = config duration "online.ttl" + val RankingTtl = config duration "ranking.ttl" val CollectionUser = config getString "collection.user" val CollectionHistory = config getString "collection.history" } @@ -34,6 +35,8 @@ final class Env( lazy val onlineUserIdMemo = new ExpireSetMemo(ttl = OnlineTtl) + lazy val ranking = new Ranking(ttl = RankingTtl) + val forms = DataForm def usernameOption(id: String): Fu[Option[String]] = cached username id diff --git a/modules/user/src/main/Ranking.scala b/modules/user/src/main/Ranking.scala new file mode 100644 index 0000000000..472771041c --- /dev/null +++ b/modules/user/src/main/Ranking.scala @@ -0,0 +1,24 @@ +package lila.user + +import scala.concurrent.duration._ + +import play.api.libs.json.Json + +import lila.db.api._ +import lila.db.Implicits._ +import lila.memo.AsyncCache +import tube.userTube + +final class Ranking(ttl: Duration) { + + def get(id: String): Fu[Option[Int]] = cache(true) map (_ get id) + + private val cache = AsyncCache.single(compute, timeToLive = ttl) + + private def compute: Fu[Map[String, Int]] = + $primitive( + UserRepo.enabledQuery ++ Json.obj("elo" -> $gt(User.STARTING_ELO)), + "_id", + _ sort UserRepo.sortEloDesc + )(_.asOpt[String]) map { _.pp.zipWithIndex.toMap } +} diff --git a/todo b/todo index 4b0011eaf9..3fdfab7de9 100644 --- a/todo +++ b/todo @@ -59,6 +59,9 @@ check team average elo http://en.lichess.org/inbox/benuegti#bottom if game ends during move -> bug challenge friends computer players ranks once a day +lobby don't show duplicated entries +prevent double lobby entry per browser +players world map ---