lila/modules/pool/src/main/GameStarter.scala

86 lines
2.5 KiB
Scala
Raw Normal View History

2016-11-30 07:06:24 -07:00
package lila.pool
import scala.concurrent.duration._
2019-12-13 07:30:20 -07:00
import lila.game.{ Game, GameRepo, IdGenerator, Player }
import lila.rating.Perf
2016-11-30 07:06:24 -07:00
import lila.user.{ User, UserRepo }
2019-12-13 07:30:20 -07:00
final private class GameStarter(
2019-12-01 11:03:39 -07:00
userRepo: UserRepo,
gameRepo: GameRepo,
idGenerator: IdGenerator,
onStart: Game.Id => Unit
2020-06-24 03:37:18 -06:00
)(implicit
ec: scala.concurrent.ExecutionContext,
system: akka.actor.ActorSystem
) {
2016-12-01 03:23:59 -07:00
2019-10-20 16:33:33 -06:00
import PoolApi._
private val workQueue = new lila.hub.AsyncActorSequencer(maxSize = 32, timeout = 10 seconds, name = "gameStarter")
2020-05-05 22:11:15 -06:00
def apply(pool: PoolConfig, couples: Vector[MatchMaking.Couple]): Funit =
couples.nonEmpty ?? {
workQueue {
val userIds = couples.flatMap(_.userIds)
userRepo.perfOf(userIds, pool.perfType) flatMap { perfs =>
2020-05-14 20:03:22 -06:00
idGenerator.games(couples.size) flatMap { ids =>
couples.zip(ids).map((one(pool, perfs) _).tupled).sequenceFu.map { pairings =>
lila.common.Bus.publish(Pairings(pairings.flatten.toList), "poolPairings")
}
2020-05-05 22:11:15 -06:00
}
2019-10-20 16:33:33 -06:00
}
2016-12-01 15:48:46 -07:00
}
}
2019-12-13 07:30:20 -07:00
private def one(pool: PoolConfig, perfs: Map[User.ID, Perf])(
2020-05-14 20:03:22 -06:00
couple: MatchMaking.Couple,
id: Game.ID
2019-12-13 07:30:20 -07:00
): Fu[Option[Pairing]] = {
import couple._
2020-08-12 00:23:33 -06:00
import cats.implicits._
2020-09-21 01:28:28 -06:00
(perfs.get(p1.userId), perfs.get(p2.userId)).mapN((_, _)) ?? { case (perf1, perf2) =>
for {
p1White <- userRepo.firstGetsWhite(p1.userId, p2.userId)
(whitePerf, blackPerf) = if (p1White) perf1 -> perf2 else perf2 -> perf1
(whiteMember, blackMember) = if (p1White) p1 -> p2 else p2 -> p1
game = makeGame(
id,
pool,
whiteMember.userId -> whitePerf,
blackMember.userId -> blackPerf
).start
_ <- gameRepo insertDenormalized game
} yield {
onStart(Game.Id(game.id))
Pairing(
game,
whiteSri = whiteMember.sri,
blackSri = blackMember.sri
).some
}
2016-11-30 07:06:24 -07:00
}
}
2016-11-30 07:06:24 -07:00
private def makeGame(
2020-05-14 20:03:22 -06:00
id: Game.ID,
2019-12-13 07:30:20 -07:00
pool: PoolConfig,
whiteUser: (User.ID, Perf),
blackUser: (User.ID, Perf)
2020-05-05 22:11:15 -06:00
) =
2020-05-14 20:03:22 -06:00
Game(
id = id,
2020-05-05 22:11:15 -06:00
chess = chess.Game(
situation = chess.Situation(chess.variant.Standard),
clock = pool.clock.toClock.some
),
whitePlayer = Player.make(chess.White, whiteUser),
blackPlayer = Player.make(chess.Black, blackUser),
mode = chess.Mode.Rated,
2020-05-14 20:03:22 -06:00
status = chess.Status.Created,
daysPerTurn = none,
metadata = Game.metadata(lila.game.Source.Pool)
2020-05-05 22:11:15 -06:00
)
2016-11-30 07:06:24 -07:00
}