collect all pairings users in one request
This commit is contained in:
parent
c427bc774e
commit
deade5fa0f
|
@ -64,6 +64,11 @@ trait CollExt { self: dsl with QueryBuilderExt =>
|
|||
ids.map(docsMap.get)(breakOut)
|
||||
}
|
||||
|
||||
def idsMap[D: BSONDocumentReader, I: BSONValueWriter](ids: Iterable[I], readPreference: ReadPreference = ReadPreference.primary)(docId: D => I): Fu[Map[I, D]] =
|
||||
byIds[D, I](ids, readPreference) map { docs =>
|
||||
docs.map(u => docId(u) -> u)(breakOut)
|
||||
}
|
||||
|
||||
def primitive[V: BSONValueReader](selector: Bdoc, field: String): Fu[List[V]] =
|
||||
coll.find(selector, $doc(field -> true))
|
||||
.list[Bdoc]()
|
||||
|
|
|
@ -411,19 +411,6 @@ object GameRepo {
|
|||
.skip(Random nextInt 1000)
|
||||
.uno[Game]
|
||||
|
||||
def findMirror(game: Game): Fu[Option[Game]] = coll.uno[Game]($doc(
|
||||
F.id -> $doc("$ne" -> game.id),
|
||||
F.playerUids $in game.userIds,
|
||||
F.status -> Status.Started.id,
|
||||
F.createdAt $gt (DateTime.now minusMinutes 15),
|
||||
F.updatedAt $gt (DateTime.now minusMinutes 5),
|
||||
"$or" -> $arr(
|
||||
$doc(s"${F.whitePlayer}.ai" -> $doc("$exists" -> true)),
|
||||
$doc(s"${F.blackPlayer}.ai" -> $doc("$exists" -> true))
|
||||
),
|
||||
F.binaryPieces -> game.binaryPieces
|
||||
))
|
||||
|
||||
def hydrateUpdatedAtAndTvAt(game: Game): Fu[Game] =
|
||||
coll.find($id(game.id), $doc(F.updatedAt -> true, F.tvAt -> true)).uno[Bdoc].map {
|
||||
_.fold(game) { o =>
|
||||
|
|
|
@ -25,10 +25,10 @@ final class AutoPairing(
|
|||
onStart: String => Unit
|
||||
) {
|
||||
|
||||
def apply(tour: Tournament, pairing: Pairing): Fu[Game] = for {
|
||||
user1 ← getUser(pairing.user1)
|
||||
user2 ← getUser(pairing.user2)
|
||||
game1 = Game.make(
|
||||
def apply(tour: Tournament, pairing: Pairing, usersMap: Map[User.ID, User]): Fu[Game] = {
|
||||
val user1 = usersMap get pairing.user1 err s"Missing pairing user $pairing"
|
||||
val user2 = usersMap get pairing.user2 err s"Missing pairing user $pairing"
|
||||
val game1 = Game.make(
|
||||
game = chess.Game(
|
||||
variantOption = tour.variant.some,
|
||||
fen = tour.position.some.filterNot(_.initial).map(_.fen)
|
||||
|
@ -49,21 +49,17 @@ final class AutoPairing(
|
|||
source = Source.Tournament,
|
||||
pgnImport = None
|
||||
)
|
||||
game2 = game1
|
||||
val game2 = game1
|
||||
.updatePlayer(Color.White, _.withUser(user1.id, PerfPicker.mainOrDefault(game1)(user1.perfs)))
|
||||
.updatePlayer(Color.Black, _.withUser(user2.id, PerfPicker.mainOrDefault(game1)(user2.perfs)))
|
||||
.withTournamentId(tour.id)
|
||||
.withId(pairing.gameId)
|
||||
.start
|
||||
_ ← (GameRepo insertDenormalized game2) >>-
|
||||
(GameRepo insertDenormalized game2) >>-
|
||||
scheduleIdleCheck(PovRef(game2.id, game2.turnColor), SecondsToDoFirstMove.secondsToMoveFor(tour), true) >>-
|
||||
onStart(game2.id)
|
||||
} yield game2
|
||||
|
||||
private def getUser(username: String): Fu[User] =
|
||||
UserRepo named username flatMap {
|
||||
_.fold(fufail[User]("No user named " + username))(fuccess)
|
||||
}
|
||||
onStart(game2.id) inject
|
||||
game2
|
||||
}
|
||||
|
||||
private def scheduleIdleCheck(povRef: PovRef, secondsToMove: Int, thenAgain: Boolean) {
|
||||
system.scheduler.scheduleOnce(secondsToMove seconds)(idleCheck(povRef, secondsToMove, thenAgain))
|
||||
|
|
|
@ -97,10 +97,10 @@ object PlayerRepo {
|
|||
selectTour(tourId) ++ $doc("m" -> $doc("$gt" -> 0))
|
||||
).cursor[Player]().gather[List]()
|
||||
|
||||
def userIds(tourId: String): Fu[List[String]] =
|
||||
private[tournament] def userIds(tourId: String): Fu[List[String]] =
|
||||
coll.distinct[String, List]("uid", selectTour(tourId).some)
|
||||
|
||||
def activeUserIds(tourId: String): Fu[List[String]] =
|
||||
private[tournament] def activeUserIds(tourId: String): Fu[List[String]] =
|
||||
coll.distinct[String, List](
|
||||
"uid", (selectTour(tourId) ++ selectActive).some
|
||||
)
|
||||
|
|
|
@ -72,13 +72,15 @@ final class TournamentApi(
|
|||
pairingLogger.warn(s"Give up making https://lichess.org/tournament/${tour.id} ${pairings.size} pairings in ${nowMillis - startAt}ms")
|
||||
lila.mon.tournament.pairing.giveup()
|
||||
funit
|
||||
case pairings => pairings.map { pairing =>
|
||||
PairingRepo.insert(pairing) >>
|
||||
autoPairing(tour, pairing) addEffect { game =>
|
||||
sendTo(tour.id, StartGame(game))
|
||||
}
|
||||
}.sequenceFu >> featureOneOf(tour, pairings, ranking) >>- {
|
||||
lila.mon.tournament.pairing.create(pairings.size)
|
||||
case pairings => UserRepo.idsMap(pairings.flatMap(_.users)) flatMap { users =>
|
||||
pairings.map { pairing =>
|
||||
PairingRepo.insert(pairing) >>
|
||||
autoPairing(tour, pairing, users) addEffect { game =>
|
||||
sendTo(tour.id, StartGame(game))
|
||||
}
|
||||
}.sequenceFu >> featureOneOf(tour, pairings, ranking) >>- {
|
||||
lila.mon.tournament.pairing.create(pairings.size)
|
||||
}
|
||||
}
|
||||
} >>- {
|
||||
val time = nowMillis - startAt
|
||||
|
|
|
@ -49,6 +49,12 @@ object UserRepo {
|
|||
def byOrderedIds(ids: Seq[ID], readPreference: ReadPreference): Fu[List[User]] =
|
||||
coll.byOrderedIds[User, User.ID](ids, readPreference)(_.id)
|
||||
|
||||
def idsMap(ids: Seq[ID], readPreference: ReadPreference = ReadPreference.secondaryPreferred): Fu[Map[User.ID, User]] =
|
||||
coll.idsMap[User, User.ID](ids, readPreference)(_.id)
|
||||
|
||||
def usersFromSecondary(userIds: Seq[ID]): Fu[List[User]] =
|
||||
byOrderedIds(userIds, ReadPreference.secondaryPreferred)
|
||||
|
||||
def enabledByIds(ids: Iterable[ID]): Fu[List[User]] =
|
||||
coll.list[User](enabledSelect ++ $inIds(ids), ReadPreference.secondaryPreferred)
|
||||
|
||||
|
@ -78,9 +84,6 @@ object UserRepo {
|
|||
_.flatMap { _.getAs[String]("_id") }
|
||||
}
|
||||
|
||||
def usersFromSecondary(userIds: Seq[ID]): Fu[List[User]] =
|
||||
byOrderedIds(userIds, ReadPreference.secondaryPreferred)
|
||||
|
||||
private[user] def allSortToints(nb: Int) =
|
||||
coll.find($empty).sort($sort desc F.toints).cursor[User]().gather[List](nb)
|
||||
|
||||
|
|
Loading…
Reference in a new issue