tune all async caches

pull/5819/head
Thibault Duplessis 2019-12-23 23:08:41 -05:00
parent 032c3bcd32
commit f7efc9ae4a
22 changed files with 90 additions and 49 deletions

View File

@ -390,15 +390,21 @@ final class Tournament(
}
private val streamerCache = env.memo.cacheApi[Tour.ID, Set[UserModel.ID]]("tournament.streamers") {
_.refreshAfterWrite(15.seconds)
_.initialCapacity(64)
.refreshAfterWrite(15.seconds)
.maximumSize(64)
.buildAsyncFuture { tourId =>
env.streamer.liveStreamApi.all.flatMap {
_.streams
.map { stream =>
env.tournament.hasUser(tourId, stream.streamer.userId) map (_ option stream.streamer.userId)
env.tournament.tournamentRepo.isUnfinished(tourId) flatMap {
_ ?? {
env.streamer.liveStreamApi.all.flatMap {
_.streams
.map { stream =>
env.tournament.hasUser(tourId, stream.streamer.userId).dmap(_ option stream.streamer.userId)
}
.sequenceFu
.dmap(_.flatten.toSet)
}
.sequenceFu
.dmap(_.flatten.toSet)
}
}
}
}

View File

@ -44,7 +44,8 @@ final class ChallengeApi(
def onlineByIdFor(id: Challenge.ID, dest: User) = repo.byIdFor(id, dest).dmap(_.filter(_.online))
val countInFor = cacheApi[User.ID, Int]("challenge.countInFor") {
_.expireAfterAccess(20 minutes)
_.initialCapacity(65536)
.expireAfterAccess(20 minutes)
.buildAsyncFuture(repo.countCreatedByDestId)
}

View File

@ -31,7 +31,8 @@ final class ChatApi(
object cached {
private val cache = cacheApi[Chat.Id, UserChat]("chat.user") {
_.expireAfterAccess(1 minute)
_.initialCapacity(128)
.expireAfterAccess(1 minute)
.buildAsyncFuture(find)
}

View File

@ -48,7 +48,8 @@ final class EvalCacheApi(
}
private val cache = cacheApi[Id, Option[EvalCacheEntry]]("evalCache") {
_.expireAfterAccess(10 minutes)
_.initialCapacity(65536)
.expireAfterAccess(5 minutes)
.buildAsyncFuture(fetchAndSetAccess)
}

View File

@ -28,7 +28,8 @@ final private class EvalCacheTruster(
}
private val userIdCache = cacheApi[User.ID, Option[TrustedUser]]("evalCache.userIdTrustCache") {
_.expireAfterWrite(10 minutes)
_.initialCapacity(256)
.expireAfterWrite(10 minutes)
.buildAsyncFuture { userId =>
userRepo named userId map2 makeTrusted
}

View File

@ -11,8 +11,8 @@ final class Recent(
cacheApi: lila.memo.CacheApi,
categIds: List[String]
)(implicit ec: scala.concurrent.ExecutionContext) {
private val ttl: FiniteDuration = 1 hour
private val nb: Int = 12
private val nb: Int = 12
private type GetTeamIds = String => Fu[List[String]]
@ -36,7 +36,8 @@ final class Recent(
}
private val cache = cacheApi[String, List[MiniForumPost]]("forum.recent") {
_.expireAfterAccess(ttl)
_.initialCapacity(2048)
.expireAfterAccess(1 hour)
.buildAsyncFuture(fetch)
}

View File

@ -12,16 +12,19 @@ final class Cached(
mongoCache: MongoCache.Builder
)(implicit ec: scala.concurrent.ExecutionContext) {
def nbImportedBy(userId: String): Fu[Int] = nbImportedCache(userId)
def clearNbImportedByCache = nbImportedCache remove _
def nbPlaying(userId: String): Fu[Int] = countShortTtl.get(Query nowPlaying userId)
def nbImportedBy(userId: User.ID): Fu[Int] = nbImportedCache(userId)
def clearNbImportedByCache = nbImportedCache remove _
def nbTotal: Fu[Int] = countCache($empty)
private val countShortTtl = cacheApi[Bdoc, Int]("game.countShortTtl") {
_.expireAfterWrite(10.seconds)
.buildAsyncFuture(gameRepo.coll.countSel)
def nbPlaying = nbPlayingCache.get _
private val nbPlayingCache = cacheApi[User.ID, Int]("game.nbPlaying") {
_.initialCapacity(256)
.expireAfterAccess(15 seconds)
.buildAsyncFuture { userId =>
gameRepo.coll.countSel(Query nowPlaying userId)
}
}
private val nbImportedCache = mongoCache[User.ID, Int](

View File

@ -45,7 +45,8 @@ final class NotifyApi(
}
private val unreadCountCache = cacheApi[Notification.Notifies, Int]("notify.unreadCountCache") {
_.expireAfterAccess(15 minutes)
_.initialCapacity(32768)
.expireAfterAccess(20 minutes)
.buildAsyncFuture(repo.unreadNotificationsCount)
}

View File

@ -48,12 +48,12 @@ final class OAuthServer(
case Array("Bearer", tokenStr) => AccessToken.Id(tokenStr)
}
private val accessTokenCache = cacheApi[AccessToken.Id, Option[AccessToken.ForAuth]](
"oauth.server.personal_access_token"
) {
_.expireAfterWrite(5 minutes)
.buildAsyncFuture(fetchAccessToken)
}
private val accessTokenCache =
cacheApi[AccessToken.Id, Option[AccessToken.ForAuth]]("oauth.server.personal_access_token") {
_.initialCapacity(16)
.expireAfterWrite(5 minutes)
.buildAsyncFuture(fetchAccessToken)
}
private def fetchAccessToken(tokenId: AccessToken.Id): Fu[Option[AccessToken.ForAuth]] =
tokenColl {

View File

@ -18,7 +18,8 @@ final class PrefApi(
private def fetchPref(id: User.ID): Fu[Option[Pref]] = coll.ext.find($id(id)).one[Pref]
private val cache = cacheApi[User.ID, Option[Pref]]("pref.fetchPref") {
_.expireAfterAccess(10 minutes)
_.initialCapacity(65536)
.expireAfterAccess(10 minutes)
.buildAsyncFuture(fetchPref)
}

View File

@ -21,7 +21,8 @@ final private class GameJson(
private case class CacheKey(gameId: Game.ID, plies: Int, onlyLast: Boolean)
private val cache = cacheApi[CacheKey, JsObject]("puzzle.gameJson") {
_.expireAfterAccess(5 minutes)
_.initialCapacity(1024)
.expireAfterAccess(5 minutes)
.maximumSize(1024)
.buildAsyncFuture(generate)
}

View File

@ -74,7 +74,9 @@ final class RelationApi(
fetchFollows(u1, u2) >>& fetchFollows(u2, u1)
private val countFollowingCache = cacheApi[ID, Int]("relation.count.following") {
_.expireAfterWrite(10 minutes)
_.initialCapacity(65536)
.expireAfterAccess(10 minutes)
.maximumSize(65536)
.buildAsyncFuture { userId =>
coll.countSel($doc("u1" -> userId, "r" -> Follow))
}
@ -85,7 +87,9 @@ final class RelationApi(
def reachedMaxFollowing(userId: ID): Fu[Boolean] = countFollowingCache get userId map (config.maxFollow <=)
private val countFollowersCache = cacheApi[ID, Int]("relation.count.followers") {
_.expireAfterAccess(10 minutes)
_.initialCapacity(65536)
.expireAfterAccess(10 minutes)
.maximumSize(65536)
.buildAsyncFuture { userId =>
coll.countSel($doc("u2" -> userId, "r" -> Follow))
}

View File

@ -354,9 +354,8 @@ final class ReportApi(
private val cache =
cacheApi[User.ID, Option[Accuracy]]("report.accuracy") {
_.refreshAfterWrite(24 hours)
_.expireAfterWrite(24 hours)
.initialCapacity(512)
.maximumSize(8192)
.buildAsyncFuture { reporterId =>
coll.ext
.find(

View File

@ -23,7 +23,8 @@ final class IpIntel(
else cache get ip
private val cache = cacheApi[IpAddress, Int]("ipIntel") {
_.expireAfterWrite(3 days)
_.initialCapacity(8192)
.expireAfterWrite(3 days)
.buildAsyncFuture { ip =>
val url = s"https://check.getipintel.net/check.php?ip=$ip&contact=${contactEmail.value}"
ws.url(url)

View File

@ -76,7 +76,8 @@ final class Env(
lazy val lightStudyCache: LightStudyCache =
cacheApi[Study.Id, Option[Study.LightStudy]]("study.lightStudyCache") {
_.expireAfterWrite(20 minutes)
_.initialCapacity(512)
.expireAfterWrite(20 minutes)
.buildAsyncFuture(studyRepo.lightById)
}

View File

@ -43,7 +43,7 @@ final class Cached(
def invalidateTeamIds = teamIdsCache invalidate _
val nbRequests = cacheApi[User.ID, Int]("team.nbRequests") {
_.expireAfterAccess(30 minutes)
_.expireAfterAccess(25 minutes)
.initialCapacity(32768)
.maximumSize(65536)
.buildAsyncFuture[User.ID, Int] { userId =>

View File

@ -14,7 +14,6 @@ final private[tournament] class Cached(
)(implicit ec: scala.concurrent.ExecutionContext, system: akka.actor.ActorSystem) {
private val createdTtl = 2 seconds
private val rankingTtl = 1 hour
val nameCache = new Syncache[Tournament.ID, Option[String]](
name = "tournament.name",
@ -37,13 +36,16 @@ final private[tournament] class Cached(
// only applies to ongoing tournaments
private val ongoingRanking = cacheApi[Tournament.ID, Ranking]("tournament.ongoingRanking") {
_.expireAfterWrite(3 seconds)
_.initialCapacity(64)
.expireAfterWrite(3 seconds)
.buildAsyncFuture(playerRepo.computeRanking)
}
// only applies to finished tournaments
private val finishedRanking = cacheApi[Tournament.ID, Ranking]("tournament.finishedRanking") {
_.expireAfterAccess(rankingTtl)
_.initialCapacity(1024)
.expireAfterAccess(1 hour)
.maximumSize(2048)
.buildAsyncFuture(playerRepo.computeRanking)
}
@ -68,7 +70,9 @@ final private[tournament] class Cached(
}
private val cache = cacheApi[SheetKey, Sheet]("tournament.sheet") {
_.expireAfterAccess(3 minutes)
_.initialCapacity(8192)
.expireAfterAccess(3 minutes)
.maximumSize(32768)
.buildAsyncFuture(compute)
}
}

View File

@ -235,7 +235,8 @@ final class JsonView(
)
private val cachableData = cacheApi[Tournament.ID, CachableData]("tournament.json.cachable") {
_.expireAfterWrite(1 second)
_.initialCapacity(16)
.expireAfterWrite(1 second)
.buildAsyncFuture { id =>
for {
tour <- tournamentRepo byId id
@ -304,7 +305,9 @@ final class JsonView(
}
private val podiumJsonCache = cacheApi[Tournament.ID, Option[JsArray]]("tournament.podiumJson") {
_.expireAfterWrite(10 seconds)
_.initialCapacity(32)
.expireAfterAccess(10 seconds)
.maximumSize(256)
.buildAsyncFuture { id =>
tournamentRepo finishedById id flatMap {
_ ?? { tour =>
@ -349,7 +352,8 @@ final class JsonView(
)
private val teamStandingCache = cacheApi[Tournament.ID, JsArray]("tournament.teamStanding") {
_.expireAfterWrite(1 second)
_.initialCapacity(4)
.expireAfterWrite(1 second)
.buildAsyncFuture { id =>
tournamentRepo.teamBattleOf(id) flatMap {
_.fold(fuccess(JsArray())) { battle =>
@ -381,7 +385,9 @@ final class JsonView(
}
private val teamInfoCache = cacheApi[(Tournament.ID, TeamID), Option[JsObject]]("tournament.teamInfo") {
_.expireAfterWrite(1 second)
_.initialCapacity(4)
.expireAfterWrite(5 seconds)
.maximumSize(32)
.buildAsyncFuture {
case (tourId, teamId) =>
tournamentRepo.teamBattleOf(tourId) flatMap {

View File

@ -453,7 +453,10 @@ final class TournamentApi(
}
private val tournamentTopCache = cacheApi[Tournament.ID, TournamentTop]("tournament.top") {
_.expireAfterWrite(3 second)
_.initialCapacity(16)
.refreshAfterWrite(3 second)
.expireAfterAccess(5 minutes)
.maximumSize(64)
.buildAsyncFuture { id =>
playerRepo.bestByTour(id, 20) dmap TournamentTop.apply
}

View File

@ -117,6 +117,9 @@ final class TournamentRepo(val coll: Coll)(implicit ec: scala.concurrent.Executi
maxPerPage = maxPerPage
)
def isUnfinished(tourId: Tournament.ID): Fu[Boolean] =
coll.exists($id(tourId) ++ unfinishedSelect)
def clockById(id: Tournament.ID): Fu[Option[chess.Clock.Config]] =
coll.primitiveOne[chess.Clock.Config]($id(id), "clock")

View File

@ -34,12 +34,14 @@ final class TournamentStandingApi(
} else compute(tour, page)
private val first = cacheApi[Tournament.ID, JsObject]("tournament.page.first") {
_.expireAfterWrite(1 second)
_.initialCapacity(16)
.expireAfterWrite(1 second)
.buildAsyncFuture { compute(_, 1) }
}
private val createdCache = cacheApi[(Tournament.ID, Int), JsObject]("tournament.page.createdCache") {
_.expireAfterWrite(15 second)
_.initialCapacity(2)
.expireAfterWrite(15 second)
.buildAsyncFuture {
case (tourId, page) => computeMaybe(tourId, page)
}

View File

@ -213,7 +213,8 @@ final private[video] class VideoApi(
private val max = 25
private val pathsCache = cacheApi[List[Tag], List[TagNb]]("video.paths") {
_.expireAfterAccess(10 minutes)
_.initialCapacity(32)
.expireAfterAccess(10 minutes)
.buildAsyncFuture { filterTags =>
val allPaths =
if (filterTags.isEmpty) allPopular map { tags =>