tweak cached paginators

pull/9901/head
Thibault Duplessis 2021-09-28 12:13:56 +02:00
parent c38af23730
commit 70a3f59b55
3 changed files with 69 additions and 83 deletions

View File

@ -11,7 +11,7 @@ import lila.common.config._
import lila.common.Json.jodaWrites import lila.common.Json.jodaWrites
import lila.common.paginator.{ Paginator, PaginatorJson } import lila.common.paginator.{ Paginator, PaginatorJson }
import lila.db.dsl._ import lila.db.dsl._
import lila.db.paginator.{ Adapter, CachedAdapter } import lila.db.paginator.Adapter
import lila.game.BSONHandlers._ import lila.game.BSONHandlers._
import lila.game.Game.{ BSONFields => G } import lila.game.Game.{ BSONFields => G }
import lila.game.JsonView._ import lila.game.JsonView._
@ -39,39 +39,37 @@ final private[api] class GameApi(
page: Int page: Int
): Fu[JsObject] = ): Fu[JsObject] =
Paginator( Paginator(
adapter = new CachedAdapter( adapter = new Adapter[Game](
adapter = new Adapter[Game]( collection = gameRepo.coll,
collection = gameRepo.coll, selector = {
selector = { if (~playing) lila.game.Query.nowPlaying(user.id)
if (~playing) lila.game.Query.nowPlaying(user.id)
else
$doc(
G.playerUids -> user.id,
G.status $gte chess.Status.Mate.id,
G.analysed -> analysed.map[BSONValue] {
case true => BSONBoolean(true)
case _ => $doc("$exists" -> false)
}
)
} ++ $doc(
G.rated -> rated.map[BSONValue] {
case true => BSONBoolean(true)
case _ => $doc("$exists" -> false)
}
),
projection = none,
sort = $doc(G.createdAt -> -1),
readPreference = ReadPreference.secondaryPreferred
),
nbResults =
if (~playing) gameCache.nbPlaying(user.id)
else else
fuccess { $doc(
rated.fold(user.count.game) { G.playerUids -> user.id,
case true => user.count.rated G.status $gte chess.Status.Mate.id,
case _ => user.count.casual G.analysed -> analysed.map[BSONValue] {
case true => BSONBoolean(true)
case _ => $doc("$exists" -> false)
} }
)
} ++ $doc(
G.rated -> rated.map[BSONValue] {
case true => BSONBoolean(true)
case _ => $doc("$exists" -> false)
}
),
projection = none,
sort = $doc(G.createdAt -> -1),
readPreference = ReadPreference.secondaryPreferred
).withNbResults(
if (~playing) gameCache.nbPlaying(user.id)
else
fuccess {
rated.fold(user.count.game) {
case true => user.count.rated
case _ => user.count.casual
} }
}
), ),
currentPage = page, currentPage = page,
maxPerPage = nb maxPerPage = nb
@ -98,32 +96,30 @@ final private[api] class GameApi(
page: Int page: Int
): Fu[JsObject] = ): Fu[JsObject] =
Paginator( Paginator(
adapter = new CachedAdapter( adapter = new Adapter[Game](
adapter = new Adapter[Game]( collection = gameRepo.coll,
collection = gameRepo.coll, selector = {
selector = { if (~playing) lila.game.Query.nowPlayingVs(users._1.id, users._2.id)
if (~playing) lila.game.Query.nowPlayingVs(users._1.id, users._2.id) else
else lila.game.Query.opponents(users._1, users._2) ++ $doc(
lila.game.Query.opponents(users._1, users._2) ++ $doc( G.status $gte chess.Status.Mate.id,
G.status $gte chess.Status.Mate.id, G.analysed -> analysed.map[BSONValue] {
G.analysed -> analysed.map[BSONValue] { case true => BSONBoolean(true)
case true => BSONBoolean(true) case _ => $doc("$exists" -> false)
case _ => $doc("$exists" -> false) }
} )
) } ++ $doc(
} ++ $doc( G.rated -> rated.map[BSONValue] {
G.rated -> rated.map[BSONValue] { case true => BSONBoolean(true)
case true => BSONBoolean(true) case _ => $doc("$exists" -> false)
case _ => $doc("$exists" -> false) }
}
),
projection = none,
sort = $doc(G.createdAt -> -1),
readPreference = ReadPreference.secondaryPreferred
), ),
nbResults = projection = none,
if (~playing) gameCache.nbPlaying(users._1.id) sort = $doc(G.createdAt -> -1),
else crosstableApi(users._1.id, users._2.id).dmap(_.nbGames) readPreference = ReadPreference.secondaryPreferred
).withNbResults(
if (~playing) gameCache.nbPlaying(users._1.id)
else crosstableApi(users._1.id, users._2.id).dmap(_.nbGames)
), ),
currentPage = page, currentPage = page,
maxPerPage = nb maxPerPage = nb

View File

@ -15,20 +15,14 @@ final class PaginatorBuilder(gameRepo: GameRepo)(implicit ec: scala.concurrent.E
apply(selector, Query.sortCreated, nb) _ apply(selector, Query.sortCreated, nb) _
def apply(selector: Bdoc, sort: Bdoc, nb: Option[Int] = None)(page: Int): Fu[Paginator[Game]] = def apply(selector: Bdoc, sort: Bdoc, nb: Option[Int] = None)(page: Int): Fu[Paginator[Game]] =
apply(nb.fold(noCacheAdapter(selector, sort)) { cached => apply(nb.fold[AdapterLike[Game]](noCacheAdapter(selector, sort)) { cached =>
cacheAdapter(selector, sort, fuccess(cached)) noCacheAdapter(selector, sort) withNbResults fuccess(cached)
})(page) })(page)
private def apply(adapter: AdapterLike[Game])(page: Int): Fu[Paginator[Game]] = private def apply(adapter: AdapterLike[Game])(page: Int): Fu[Paginator[Game]] =
paginator(adapter, page) paginator(adapter, page)
private def cacheAdapter(selector: Bdoc, sort: Bdoc, nbResults: Fu[Int]): AdapterLike[Game] = private def noCacheAdapter(selector: Bdoc, sort: Bdoc) =
new CachedAdapter(
adapter = noCacheAdapter(selector, sort),
nbResults = nbResults
)
private def noCacheAdapter(selector: Bdoc, sort: Bdoc): AdapterLike[Game] =
new Adapter[Game]( new Adapter[Game](
collection = gameRepo.coll, collection = gameRepo.coll,
selector = selector, selector = selector,

View File

@ -104,26 +104,22 @@ final class RelationApi(
coll.countSel($doc("u1" -> userId, "r" -> Block)) coll.countSel($doc("u1" -> userId, "r" -> Block))
def followingPaginatorAdapter(userId: ID) = def followingPaginatorAdapter(userId: ID) =
new CachedAdapter[Followed]( new Adapter[Followed](
adapter = new Adapter[Followed]( collection = coll,
collection = coll, selector = $doc("u1" -> userId, "r" -> Follow),
selector = $doc("u1" -> userId, "r" -> Follow), projection = $doc("u2" -> true, "_id" -> false).some,
projection = $doc("u2" -> true, "_id" -> false).some, sort = $empty
sort = $empty ).withNbResults(countFollowing(userId))
), .map(_.userId)
nbResults = countFollowing(userId)
).map(_.userId)
def followersPaginatorAdapter(userId: ID) = def followersPaginatorAdapter(userId: ID) =
new CachedAdapter[Follower]( new Adapter[Follower](
adapter = new Adapter[Follower]( collection = coll,
collection = coll, selector = $doc("u2" -> userId, "r" -> Follow),
selector = $doc("u2" -> userId, "r" -> Follow), projection = $doc("u1" -> true, "_id" -> false).some,
projection = $doc("u1" -> true, "_id" -> false).some, sort = $empty
sort = $empty ).withNbResults(countFollowers(userId))
), .map(_.userId)
nbResults = countFollowers(userId)
).map(_.userId)
def blockingPaginatorAdapter(userId: ID) = def blockingPaginatorAdapter(userId: ID) =
new Adapter[Blocked]( new Adapter[Blocked](