update user ranking every 10 minutes

pull/83/head
Thibault Duplessis 2013-06-04 12:05:41 +02:00
parent 4a52457fbb
commit 8c0fce29a8
6 changed files with 46 additions and 12 deletions

View File

@ -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)

View File

@ -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,

View File

@ -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)
}

View File

@ -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

View File

@ -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 }
}

3
todo
View File

@ -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
---