diff --git a/app/controllers/Tournament.scala b/app/controllers/Tournament.scala index 837e901db1..38422eaf13 100644 --- a/app/controllers/Tournament.scala +++ b/app/controllers/Tournament.scala @@ -2,12 +2,13 @@ package controllers import play.api.libs.json._ import play.api.mvc._ +import scala.concurrent.duration._ import lila.api.Context import lila.app._ import lila.common.HTTPRequest import lila.game.{ Pov, GameRepo } -import lila.tournament.{ System, TournamentRepo, PairingRepo } +import lila.tournament.{ System, TournamentRepo, PairingRepo, VisibleTournaments, Tournament => Tour } import views._ object Tournament extends LilaController { @@ -17,6 +18,15 @@ object Tournament extends LilaController { private def tournamentNotFound(implicit ctx: Context) = NotFound(html.tournament.notFound()) + private[controllers] val upcomingCache = Env.memo.asyncCache.single[(VisibleTournaments, List[Tour])]( + name = "tournament.home", + for { + visible <- env.api.fetchVisibleTournaments + scheduled <- repo.scheduledDedup + } yield (visible, scheduled), + expireAfter = _.ExpireAfterWrite(3 seconds) + ) + def home(page: Int) = Open { implicit ctx => negotiate( html = Reasonable(page, 20) { @@ -26,8 +36,7 @@ object Tournament extends LilaController { _ <- Env.user.lightUserApi preloadMany pag.currentPageResults.flatMap(_.winnerId) } yield Ok(html.tournament.finishedPaginator(pag)) else for { - visible <- env.api.fetchVisibleTournaments - scheduled <- repo.scheduledDedup + (visible, scheduled) <- upcomingCache.get finished <- finishedPaginator winners <- env.winners.all _ <- Env.user.lightUserApi preloadMany { @@ -40,7 +49,7 @@ object Tournament extends LilaController { } }, api = _ => for { - visible <- env.api.fetchVisibleTournaments + (visible, _) <- upcomingCache.get scheduleJson <- env scheduleJsonView visible } yield Ok(scheduleJson) ) @@ -197,11 +206,11 @@ object Tournament extends LilaController { } def limitedInvitation = Auth { implicit ctx => me => - env.api.fetchVisibleTournaments.flatMap { tours => - lila.tournament.TournamentInviter.findNextFor(me, tours, env.verify.canEnter(me)) - } map { - case None => Redirect(routes.Tournament.home(1)) - case Some(t) => Redirect(routes.Tournament.show(t.id)) + for { + (tours, _) <- upcomingCache.get + res <- lila.tournament.TournamentInviter.findNextFor(me, tours, env.verify.canEnter(me)) + } yield res.fold(Redirect(routes.Tournament.home(1))) { t => + Redirect(routes.Tournament.show(t.id)) } } diff --git a/modules/tournament/src/main/TournamentRepo.scala b/modules/tournament/src/main/TournamentRepo.scala index aaaa64957e..e1120463da 100644 --- a/modules/tournament/src/main/TournamentRepo.scala +++ b/modules/tournament/src/main/TournamentRepo.scala @@ -75,7 +75,7 @@ object TournamentRepo { coll.find(startedSelect).sort($doc("createdAt" -> -1)).list[Tournament](None) def publicStarted: Fu[List[Tournament]] = - coll.find(startedSelect ++ $doc("private" -> $doc("$exists" -> false))) + coll.find(startedSelect ++ $doc("private" $exists false)) .sort($doc("createdAt" -> -1)) .list[Tournament]() @@ -87,7 +87,7 @@ object TournamentRepo { def finishedNotable(limit: Int): Fu[List[Tournament]] = coll.find(finishedSelect ++ $doc( "$or" -> $arr( - $doc("nbPlayers" -> $doc("$gte" -> 15)), + $doc("nbPlayers" $gte 15), scheduledSelect ) )) @@ -110,44 +110,43 @@ object TournamentRepo { def setStatus(tourId: String, status: Status) = coll.update( $id(tourId), - $doc("$set" -> $doc("status" -> status.id)) + $set("status" -> status.id) ).void def setNbPlayers(tourId: String, nb: Int) = coll.update( $id(tourId), - $doc("$set" -> $doc("nbPlayers" -> nb)) + $set("nbPlayers" -> nb) ).void def setWinnerId(tourId: String, userId: String) = coll.update( $id(tourId), - $doc("$set" -> $doc("winner" -> userId)) + $set("winner" -> userId) ).void def setFeaturedGameId(tourId: String, gameId: String) = coll.update( $id(tourId), - $doc("$set" -> $doc("featured" -> gameId)) + $set("featured" -> gameId) ).void def featuredGameId(tourId: String) = coll.primitiveOne[String]($id(tourId), "featured") private def allCreatedSelect(aheadMinutes: Int) = createdSelect ++ $doc( "$or" -> $arr( - $doc("schedule" -> $doc("$exists" -> false)), - $doc("startsAt" -> $doc("$lt" -> (DateTime.now plusMinutes aheadMinutes))) + $doc("schedule" $exists false), + $doc("startsAt" $lt (DateTime.now plusMinutes aheadMinutes)) ) ) def publicCreatedSorted(aheadMinutes: Int): Fu[List[Tournament]] = coll.find( - allCreatedSelect(aheadMinutes) ++ $doc("private" -> $doc("$exists" -> false)) + allCreatedSelect(aheadMinutes) ++ $doc("private" $exists false) ).sort($doc("startsAt" -> 1)).list[Tournament](none) def allCreated(aheadMinutes: Int): Fu[List[Tournament]] = coll.find(allCreatedSelect(aheadMinutes)).cursor[Tournament]().gather[List]() - private def stillWorthEntering: Fu[List[Tournament]] = - coll.find(startedSelect ++ $doc( - "private" -> $doc("$exists" -> false) - )).sort($doc("startsAt" -> 1)).list[Tournament](none) map { + private def stillWorthEntering: Fu[List[Tournament]] = coll.find( + startedSelect ++ $doc("private" $exists false) + ).sort($doc("startsAt" -> 1)).list[Tournament](none) map { _.filter(_.isStillWorthEntering) }