82 lines
2.4 KiB
Scala
82 lines
2.4 KiB
Scala
package lila.user
|
|
|
|
import scala.concurrent.duration._
|
|
|
|
import org.joda.time.DateTime
|
|
import reactivemongo.bson._
|
|
|
|
import lila.common.{ LightUser, Every, AtMost }
|
|
import lila.db.dsl._
|
|
import lila.memo.PeriodicRefreshCache
|
|
import lila.rating.{ Perf, PerfType }
|
|
import User.{ LightPerf, LightCount }
|
|
|
|
final class Cached(
|
|
userColl: Coll,
|
|
nbTtl: FiniteDuration,
|
|
onlineUserIds: () => Set[User.ID],
|
|
mongoCache: lila.memo.MongoCache.Builder,
|
|
asyncCache: lila.memo.AsyncCache.Builder,
|
|
rankingApi: RankingApi
|
|
)(implicit system: akka.actor.ActorSystem) {
|
|
|
|
private implicit val LightUserBSONHandler = Macros.handler[LightUser]
|
|
private implicit val LightPerfBSONHandler = Macros.handler[LightPerf]
|
|
private implicit val LightCountBSONHandler = Macros.handler[LightCount]
|
|
|
|
val top10 = new PeriodicRefreshCache[Perfs.Leaderboards](
|
|
Every(1 minute),
|
|
AtMost(1 minute),
|
|
f = () => rankingApi fetchLeaderboard 10,
|
|
default = Perfs.emptyLeaderboards,
|
|
logger = logger,
|
|
initialDelay = 30 seconds
|
|
)
|
|
|
|
val top200Perf = mongoCache[Perf.ID, List[User.LightPerf]](
|
|
prefix = "user:top200:perf",
|
|
f = (perf: Perf.ID) => rankingApi.topPerf(perf, 200),
|
|
timeToLive = 16 minutes,
|
|
keyToString = _.toString
|
|
)
|
|
|
|
private val topWeekCache = mongoCache.single[List[User.LightPerf]](
|
|
prefix = "user:top:week",
|
|
f = PerfType.leaderboardable.map { perf =>
|
|
rankingApi.topPerf(perf.id, 1)
|
|
}.sequenceFu.map(_.flatten),
|
|
timeToLive = 9 minutes
|
|
)
|
|
|
|
def topWeek = topWeekCache.apply _
|
|
|
|
val topNbGame = mongoCache[Int, List[User.LightCount]](
|
|
prefix = "user:top:nbGame",
|
|
f = nb => UserRepo topNbGame nb map { _ map (_.lightCount) },
|
|
timeToLive = 74 minutes,
|
|
keyToString = _.toString
|
|
)
|
|
|
|
private val top50OnlineCache = new lila.memo.PeriodicRefreshCache[List[User]](
|
|
every = Every(30 seconds),
|
|
atMost = AtMost(30 seconds),
|
|
f = () => UserRepo.byIdsSortRatingNoBot(onlineUserIds(), 50),
|
|
default = Nil,
|
|
logger = logger branch "top50online",
|
|
initialDelay = 15 seconds
|
|
)
|
|
def getTop50Online = top50OnlineCache.get
|
|
|
|
def rankingsOf(userId: User.ID): Map[PerfType, Int] = rankingApi.weeklyStableRanking of userId
|
|
|
|
object ratingDistribution {
|
|
def apply(perf: PerfType) = rankingApi.weeklyRatingDistribution(perf)
|
|
}
|
|
|
|
val botIds = asyncCache.single[Set[User.ID]](
|
|
name = "user.botIds",
|
|
f = UserRepo.botIds,
|
|
expireAfter = _.ExpireAfterWrite(10 minutes)
|
|
)
|
|
}
|