add player berserk flag to tournament games API without extra DB reqs

closes #5955
pull/5961/head
Thibault Duplessis 2020-01-26 09:28:47 -06:00
parent 50eb96a370
commit 264fdd61f4
3 changed files with 34 additions and 9 deletions

View File

@ -85,17 +85,40 @@ final class GameApiV2(
def exportByTournament(config: ByTournamentConfig): Source[String, _] =
pairingRepo
.sortedGameIdsCursor(
.sortedCursor(
tournamentId = config.tournamentId,
batchSize = config.perSecond.value
)
.documentSource()
.grouped(config.perSecond.value)
.map(_.flatMap(_.getAsOpt[Game.ID]("_id")))
.throttle(1, 1 second)
.mapAsync(1)(gameRepo.gamesFromSecondary)
.mapAsync(1) { pairings =>
gameRepo.gameOptionsFromSecondary(pairings.map(_.gameId)) map {
_.zip(pairings) collect {
case (Some(game), pairing) => game -> pairing
}
}
}
.mapConcat(identity)
.via(preparationFlow(config))
.mapAsync(4) {
case (game, pairing) => enrich(config.flags)(game) dmap { _ -> pairing }
}
.mapAsync(4) {
case ((game, fen, analysis), pairing) =>
config.format match {
case Format.PGN => pgnDump.formatter(config.flags)(game, fen, analysis)
case Format.JSON =>
def addBerserk(color: chess.Color)(json: JsObject) =
if (pairing berserkOf color)
json deepMerge Json.obj("players" -> Json.obj(color.name -> Json.obj("berserk" -> true)))
else json
toJson(game, fen, analysis, config.flags) dmap
addBerserk(chess.White) dmap
addBerserk(chess.Black) dmap { json =>
s"${Json.stringify(json)}\n"
}
}
}
private def preparationFlow(config: Config) =
Flow[Game]

View File

@ -51,6 +51,8 @@ case class Pairing(
else if (userId == user2) berserk2
else false
def berserkOf(color: Color) = color.fold(berserk1, berserk2)
def similar(other: Pairing) = other.contains(user1, user2)
}

View File

@ -182,16 +182,16 @@ final class PairingRepo(coll: Coll)(implicit ec: scala.concurrent.ExecutionConte
.void
}
def sortedGameIdsCursor(
def sortedCursor(
tournamentId: Tournament.ID,
batchSize: Int = 0,
readPreference: ReadPreference = ReadPreference.secondaryPreferred
): AkkaStreamCursor[Bdoc] =
coll
.find(selectTour(tournamentId), $id(true).some)
): AkkaStreamCursor[Pairing] =
coll.ext
.find(selectTour(tournamentId))
.sort(recentSort)
.batchSize(batchSize)
.cursor[Bdoc](readPreference)
.cursor[Pairing](readPreference)
private[tournament] def rawStats(tourId: Tournament.ID): Fu[List[Bdoc]] = {
coll.aggregateList(maxDocs = 3) { framework =>