no longer save rematch IDs in DB

sitcounter-warn-close
Thibault Duplessis 2019-08-24 11:53:09 +02:00
parent 2782cfdecc
commit 7e350c56ce
11 changed files with 66 additions and 44 deletions

View File

@ -2,14 +2,17 @@ package lila.bot
import akka.actor._
import lila.game.Game
final class Env(
system: ActorSystem,
hub: lila.hub.Env,
onlineUserIds: lila.memo.ExpireSetMemo,
lightUserApi: lila.user.LightUserApi
lightUserApi: lila.user.LightUserApi,
rematchOf: Game.ID => Option[Game.ID]
) {
lazy val jsonView = new BotJsonView(lightUserApi)
lazy val jsonView = new BotJsonView(lightUserApi, rematchOf)
lazy val gameStateStream = new GameStateStream(system, jsonView)
@ -24,6 +27,7 @@ object Env {
system = lila.common.PlayApp.system,
hub = lila.hub.Env.current,
onlineUserIds = lila.user.Env.current.onlineUserIdMemo,
lightUserApi = lila.user.Env.current.lightUserApi
lightUserApi = lila.user.Env.current.lightUserApi,
rematchOf = lila.game.Env.current.rematches.getIfPresent
)
}

View File

@ -8,7 +8,8 @@ import lila.game.JsonView._
import lila.game.{ Game, Pov, GameRepo }
final class BotJsonView(
lightUserApi: lila.user.LightUserApi
lightUserApi: lila.user.LightUserApi,
rematchOf: Game.ID => Option[Game.ID]
) {
def gameFull(game: Game): Fu[JsObject] = GameRepo.withInitialFen(game) flatMap gameFull
@ -53,7 +54,7 @@ final class BotJsonView(
"bdraw" -> game.blackPlayer.isOfferingDraw,
"wdraw" -> game.whitePlayer.isOfferingDraw
)
.add("rematch" -> game.next)
.add("rematch" -> rematchOf(game.id))
}
}

View File

@ -1,7 +1,9 @@
package lila.game
import akka.actor._
import com.github.blemale.scaffeine.{ Cache, Scaffeine }
import com.typesafe.config.Config
import scala.concurrent.duration._
final class Env(
config: Config,
@ -78,6 +80,14 @@ final class Env(
lazy val gamesByUsersStream = new GamesByUsersStream(system)
lazy val bestOpponents = new BestOpponents
lazy val rematches: Cache[Game.ID, Game.ID] = Scaffeine()
.expireAfterWrite(3 hour)
.build[Game.ID, Game.ID]
lazy val jsonView = new JsonView(
rematchOf = rematches.getIfPresent
)
}
object Env {

View File

@ -303,13 +303,12 @@ object GameRepo {
def setImportCreatedAt(g: Game) =
coll.update($id(g.id), $set("pgni.ca" -> g.createdAt)).void
def saveNext(game: Game, nextId: ID): Funit = coll.update(
def unsetRematch(game: Game): Funit = coll.update(
$id(game.id),
$set(F.next -> nextId) ++
$unset(
"p0." + Player.BSONFields.isOfferingRematch,
"p1." + Player.BSONFields.isOfferingRematch
)
$unset(
"p0." + Player.BSONFields.isOfferingRematch,
"p1." + Player.BSONFields.isOfferingRematch
)
).void
def initialFen(gameId: ID): Fu[Option[FEN]] =

View File

@ -6,9 +6,11 @@ import chess.format.{ FEN, Forsyth }
import chess.variant.Crazyhouse
import chess.{ Color, Clock }
object JsonView {
final class JsonView(rematchOf: Game.ID => Option[Game.ID]) {
def gameJson(game: Game, initialFen: Option[FEN]) = Json.obj(
import JsonView._
def apply(game: Game, initialFen: Option[FEN]) = Json.obj(
"id" -> game.id,
"variant" -> game.variant,
"speed" -> game.speed.key,
@ -28,7 +30,10 @@ object JsonView {
.add("winner" -> game.winnerColor)
.add("lastMove" -> game.lastMoveKeys)
.add("check" -> game.situation.checkSquare.map(_.key))
.add("rematch" -> game.next)
.add("rematch" -> rematchOf(game.id))
}
object JsonView {
implicit val statusWrites: OWrites[chess.Status] = OWrites { s =>
Json.obj(

View File

@ -4,6 +4,7 @@ import akka.actor._
import akka.pattern.ask
import com.typesafe.config.Config
import scala.concurrent.duration._
import com.github.blemale.scaffeine.Cache
import actorApi.{ GetSocketStatus, SocketStatus }
@ -25,10 +26,11 @@ final class Env(
playban: lila.playban.PlaybanApi,
lightUser: lila.common.LightUser.Getter,
userJsonView: lila.user.JsonView,
gameJsonView: lila.game.JsonView,
rankingApi: lila.user.RankingApi,
notifyApi: lila.notify.NotifyApi,
uciMemo: lila.game.UciMemo,
rematch960Cache: lila.memo.ExpireSetMemo,
rematches: Cache[Game.ID, Game.ID],
divider: lila.game.Divider,
prefApi: lila.pref.PrefApi,
historyApi: lila.history.HistoryApi,
@ -227,7 +229,7 @@ final class Env(
private lazy val rematcher = new Rematcher(
messenger = messenger,
onStart = onStart,
rematch960Cache = rematch960Cache,
rematches = rematches,
bus = bus
)
@ -260,6 +262,7 @@ final class Env(
lazy val jsonView = new JsonView(
noteApi = noteApi,
userJsonView = userJsonView,
gameJsonView = gameJsonView,
getSocketStatus = getSocketStatus,
canTakeback = takebacker.isAllowedIn,
canMoretime = moretimer.isAllowedIn,
@ -326,10 +329,11 @@ object Env {
playban = lila.playban.Env.current.api,
lightUser = lila.user.Env.current.lightUser,
userJsonView = lila.user.Env.current.jsonView,
gameJsonView = lila.game.Env.current.jsonView,
rankingApi = lila.user.Env.current.rankingApi,
notifyApi = lila.notify.Env.current.api,
uciMemo = lila.game.Env.current.uciMemo,
rematch960Cache = lila.game.Env.current.cached.rematch960,
rematches = lila.game.Env.current.rematches,
divider = lila.game.Env.current.divider,
prefApi = lila.pref.Env.current.api,
historyApi = lila.history.Env.current.api,

View File

@ -19,6 +19,7 @@ import actorApi.SocketStatus
final class JsonView(
noteApi: NoteApi,
userJsonView: lila.user.JsonView,
gameJsonView: lila.game.JsonView,
getSocketStatus: Game.ID => Fu[SocketStatus],
canTakeback: Game => Fu[Boolean],
canMoretime: Game => Fu[Boolean],
@ -64,7 +65,7 @@ final class JsonView(
case socket ~ opponentUser ~ takebackable ~ moretimeable =>
import pov._
Json.obj(
"game" -> gameJson(game, initialFen),
"game" -> gameJsonView(game, initialFen),
"player" -> {
commonPlayerJson(game, player, playerUser, withFlags) ++ Json.obj(
"id" -> playerId,
@ -154,7 +155,7 @@ final class JsonView(
case (socket, (playerUser, opponentUser)) =>
import pov._
Json.obj(
"game" -> gameJson(game, initialFen)
"game" -> gameJsonView(game, initialFen)
.add("moveCentis" -> (withFlags.movetimes ?? game.moveTimes.map(_.map(_.centis))))
.add("division" -> withFlags.division.option(divider(game, initialFen)))
.add("opening" -> game.opening)

View File

@ -4,7 +4,7 @@ import chess.format.Forsyth
import chess.variant._
import chess.{ Game => ChessGame, Board, Color => ChessColor, Castles, Clock, Situation }
import ChessColor.{ White, Black }
import com.github.blemale.scaffeine.{ Cache, Scaffeine }
import com.github.blemale.scaffeine.Cache
import scala.concurrent.duration._
import lila.game.{ GameRepo, Game, Event, Progress, Pov, Source, AnonCookie, PerfPicker }
@ -13,19 +13,15 @@ import lila.user.{ User, UserRepo }
private[round] final class Rematcher(
messenger: Messenger,
onStart: String => Unit,
rematch960Cache: ExpireSetMemo,
onStart: Game.ID => Unit,
rematches: Cache[Game.ID, Game.ID],
bus: lila.common.Bus
) {
private val rematchCreated: Cache[Game.ID, Game.ID] = Scaffeine()
.expireAfterWrite(1 minute)
.build[Game.ID, Game.ID]
def yes(pov: Pov)(implicit proxy: GameProxy): Fu[Events] = pov match {
case Pov(game, color) if game playerCanRematch color =>
if (game.opponent(color).isOfferingRematch || game.opponent(color).isAi)
game.next.fold(rematchJoin(pov))(rematchExists(pov))
rematches.getIfPresent(game.id).fold(rematchJoin(pov))(rematchExists(pov))
else rematchCreate(pov)
case _ => fuccess(List(Event.ReloadOwner))
}
@ -42,23 +38,20 @@ private[round] final class Rematcher(
case _ => fuccess(List(Event.ReloadOwner))
}
private def rematchExists(pov: Pov)(nextId: String): Fu[Events] =
private def rematchExists(pov: Pov)(nextId: Game.ID): Fu[Events] =
GameRepo game nextId flatMap {
_.fold(rematchJoin(pov))(g => fuccess(redirectEvents(g)))
}
private def rematchJoin(pov: Pov): Fu[Events] =
rematchCreated.getIfPresent(pov.gameId) match {
rematches.getIfPresent(pov.gameId) match {
case None => for {
nextGame returnGame(pov) map (_.start)
_ = rematchCreated.put(pov.gameId, nextGame.id)
_ (GameRepo insertDenormalized nextGame) >>
GameRepo.saveNext(pov.game, nextGame.id) >>-
messenger.system(pov.game, _.rematchOfferAccepted) >>- {
if (pov.game.variant == Chess960 && !rematch960Cache.get(pov.gameId))
rematch960Cache.put(nextGame.id)
}
_ = rematches.put(pov.gameId, nextGame.id)
_ GameRepo insertDenormalized nextGame
_ <- GameRepo unsetRematch pov.game
} yield {
messenger.system(pov.game, _.rematchOfferAccepted)
onStart(nextGame.id)
redirectEvents(nextGame)
}
@ -78,7 +71,7 @@ private[round] final class Rematcher(
situation = initialFen flatMap { fen => Forsyth <<< fen.value }
pieces = pov.game.variant match {
case Chess960 =>
if (rematch960Cache get pov.gameId) Chess960.pieces
if (rematches getIfPresent pov.gameId isDefined) Chess960.pieces
else situation.fold(Chess960.pieces)(_.situation.board.pieces)
case FromPosition => situation.fold(Standard.pieces)(_.situation.board.pieces)
case variant => variant.pieces

View File

@ -11,7 +11,8 @@ private[tv] final class ChannelTrouper(
channel: Tv.Channel,
lightUser: lila.common.LightUser.GetterSync,
onSelect: TvTrouper.Selected => Unit,
proxyGame: Game.ID => Fu[Option[Game]]
proxyGame: Game.ID => Fu[Option[Game]],
rematchOf: Game.ID => Option[Game.ID]
) extends Trouper {
import ChannelTrouper._
@ -66,7 +67,7 @@ private[tv] final class ChannelTrouper(
private def isWayBetter(g1: Game, g2: Game) = score(g2.resetTurns) > (score(g1.resetTurns) * 1.17)
private def rematch(game: Game): Fu[Option[Game]] = game.next ?? proxyGame
private def rematch(game: Game): Fu[Option[Game]] = rematchOf(game.id) ?? proxyGame
private def bestOf(candidates: List[Game]) =
candidates sortBy { -score(_) } headOption

View File

@ -16,7 +16,8 @@ final class Env(
lightUser: lila.common.LightUser.GetterSync,
proxyGame: Game.ID => Fu[Option[Game]],
system: ActorSystem,
onSelect: Game => Unit
onSelect: Game => Unit,
rematchOf: Game.ID => Option[Game.ID]
) {
private val FeaturedSelect = config duration "featured.select"
@ -30,7 +31,8 @@ final class Env(
selectChannel,
lightUser,
onSelect,
proxyGame
proxyGame,
rematchOf
)
lazy val tv = new Tv(tvTrouper, proxyGame)
@ -49,6 +51,7 @@ object Env {
lightUser = lila.user.Env.current.lightUserSync,
proxyGame = lila.round.Env.current.proxy.gameIfPresent _,
system = lila.common.PlayApp.system,
onSelect = lila.round.Env.current.recentTvGames.put _
onSelect = lila.round.Env.current.recentTvGames.put _,
rematchOf = lila.game.Env.current.rematches.getIfPresent
)
}

View File

@ -16,7 +16,8 @@ private[tv] final class TvTrouper(
selectChannel: lila.socket.Channel,
lightUser: LightUser.GetterSync,
onSelect: Game => Unit,
proxyGame: Game.ID => Fu[Option[Game]]
proxyGame: Game.ID => Fu[Option[Game]],
rematchOf: Game.ID => Option[Game.ID]
) extends Trouper {
import TvTrouper._
@ -24,7 +25,7 @@ private[tv] final class TvTrouper(
system.lilaBus.subscribe(this, 'startGame)
private val channelTroupers: Map[Tv.Channel, ChannelTrouper] = Tv.Channel.all.map { c =>
c -> new ChannelTrouper(c, lightUser, onSelect = this.!, proxyGame)
c -> new ChannelTrouper(c, lightUser, onSelect = this.!, proxyGame, rematchOf)
}.toMap
private var channelChampions = Map[Tv.Channel, Tv.Champion]()