fix force-(resign|draw) and improve API perf (less actor ask)

This commit is contained in:
Thibault Duplessis 2014-10-20 14:13:41 +02:00
parent ebe2e6a30d
commit 7df149acf9
8 changed files with 50 additions and 31 deletions

View file

@ -5,11 +5,11 @@ import akka.pattern.ask
import com.typesafe.config.Config
import scala.concurrent.duration._
import actorApi.{ GetSocketStatus, SocketStatus }
import lila.common.PimpedConfig._
import lila.hub.actorApi.map.Ask
import lila.memo.AsyncCache
import lila.socket.actorApi.GetVersion
import actorApi.IsGone
import makeTimeout.large
final class Env(
@ -152,8 +152,8 @@ final class Env(
def version(gameId: String): Fu[Int] =
socketHub ? Ask(gameId, GetVersion) mapTo manifest[Int]
private def isGone(gameId: String, color: chess.Color): Fu[Boolean] =
socketHub ? Ask(gameId, IsGone(color)) mapTo manifest[Boolean]
private def getSocketStatus(gameId: String): Fu[SocketStatus] =
socketHub ? Ask(gameId, GetSocketStatus) mapTo manifest[SocketStatus]
private lazy val reminder = new Reminder(db(CollectionReminder))
def nowPlaying = reminder.nowPlaying
@ -161,8 +161,7 @@ final class Env(
lazy val jsonView = new JsonView(
chatApi = chatApi,
userJsonView = userJsonView,
getVersion = version,
isGone = isGone,
getSocketStatus = getSocketStatus,
canTakeback = takebacker.isAllowedByPrefs,
baseAnimationDuration = AnimationDuration,
moretimeSeconds = Moretime.toSeconds.toInt)

View file

@ -13,11 +13,12 @@ import lila.user.{ User, UserRepo }
import chess.format.Forsyth
import chess.{ Color, Clock, Variant }
import actorApi.SocketStatus
final class JsonView(
chatApi: lila.chat.ChatApi,
userJsonView: lila.user.JsonView,
getVersion: String => Fu[Int],
isGone: (String, Color) => Fu[Boolean],
getSocketStatus: String => Fu[SocketStatus],
canTakeback: Game => Fu[Boolean],
baseAnimationDuration: Duration,
moretimeSeconds: Int) {
@ -34,12 +35,11 @@ final class JsonView(
apiVersion: Int,
playerUser: Option[User],
withBlurs: Boolean): Fu[JsObject] =
getVersion(pov.game.id) zip
isGone(pov.game.id, pov.opponent.color) zip
getSocketStatus(pov.game.id) zip
(pov.opponent.userId ?? UserRepo.byId) zip
canTakeback(pov.game) zip
getPlayerChat(pov.game, playerUser) map {
case ((((version, opponentGone), opponentUser), takebackable), chat) =>
case (((socket, opponentUser), takebackable), chat) =>
import pov._
Json.obj(
"game" -> Json.obj(
@ -65,7 +65,7 @@ final class JsonView(
"player" -> Json.obj(
"id" -> playerId,
"color" -> player.color.name,
"version" -> version,
"version" -> socket.version,
"spectator" -> false,
"user" -> playerUser.map { userJsonView(_, true) },
"ratingDiff" -> player.ratingDiff,
@ -83,7 +83,8 @@ final class JsonView(
"offeringRematch" -> opponent.isOfferingRematch.option(true),
"offeringDraw" -> opponent.isOfferingDraw.option(true),
"proposingTakeback" -> opponent.isProposingTakeback.option(true),
"onGame" -> !opponentGone,
"onGame" -> socket.onGame(opponent.color),
"isGone" -> socket.isGone(opponent.color),
"hold" -> (withBlurs option hold(opponent)),
"blurs" -> (withBlurs option blurs(game, opponent))
).noNull,
@ -123,12 +124,10 @@ final class JsonView(
user: Option[User],
tv: Option[Boolean],
withBlurs: Boolean) =
getVersion(pov.game.id) zip
isGone(pov.game.id, pov.color) zip
isGone(pov.game.id, pov.opponent.color) zip
getSocketStatus(pov.game.id) zip
getWatcherChat(pov.game, user) zip
UserRepo.pair(pov.player.userId, pov.opponent.userId) map {
case ((((version, playerGone), opponentGone), chat), (playerUser, opponentUser)) =>
case ((socket, chat), (playerUser, opponentUser)) =>
import pov._
Json.obj(
"game" -> Json.obj(
@ -152,12 +151,12 @@ final class JsonView(
"clock" -> game.clock.map(clockJson),
"player" -> Json.obj(
"color" -> color.name,
"version" -> version,
"version" -> socket.version,
"spectator" -> true,
"ai" -> player.aiLevel,
"user" -> playerUser.map { userJsonView(_, true) },
"ratingDiff" -> player.ratingDiff,
"onGame" -> !playerGone,
"onGame" -> socket.onGame(player.color),
"hold" -> (withBlurs option hold(player)),
"blurs" -> (withBlurs option blurs(game, player))
).noNull,
@ -166,7 +165,7 @@ final class JsonView(
"ai" -> opponent.aiLevel,
"user" -> opponentUser.map { userJsonView(_, true) },
"ratingDiff" -> opponent.ratingDiff,
"onGame" -> !opponentGone,
"onGame" -> socket.onGame(opponent.color),
"hold" -> (withBlurs option hold(opponent)),
"blurs" -> (withBlurs option blurs(game, opponent))
).noNull,

View file

@ -45,10 +45,11 @@ private[round] final class Socket(
time = nowMillis
}
def setBye {
bye = 2
bye = 3
}
def isBye = bye > 0
def isGone = isBye && time < (nowMillis - isBye.fold(ragequitTimeout, disconnectTimeout).toMillis)
private def isBye = bye > 0
def isGone = time < (nowMillis - isBye.fold(ragequitTimeout, disconnectTimeout).toMillis)
}
private val whitePlayer = new Player(White)
@ -72,7 +73,7 @@ private[round] final class Socket(
case Bye(color) => playerDo(color, _.setBye)
case Ack(uid) => withMember(uid) { _.channel push ackEvent }
case Ack(uid) => withMember(uid) { _.channel push ackEvent }
case Broom =>
broom
@ -85,6 +86,13 @@ private[round] final class Socket(
case IsGone(color) => sender ! playerGet(color, _.isGone)
case GetSocketStatus => sender ! SocketStatus(
version = history.getVersion,
whiteOnGame = ownerOf(White).isDefined,
whiteIsGone = playerGet(White, _.isGone),
blackOnGame = ownerOf(Black).isDefined,
blackIsGone = playerGet(Black, _.isGone))
case Join(uid, user, version, color, playerId, ip, userTv) => {
val (enumerator, channel) = Concurrent.broadcast[JsValue]
val member = Member(channel, user, color, playerId, ip, userTv = userTv)

View file

@ -77,6 +77,16 @@ case class Bye(color: Color)
case class IsGone(color: Color)
case object AnalysisAvailable
case class Ack(uid: String)
case object GetSocketStatus
case class SocketStatus(
version: Int,
whiteOnGame: Boolean,
whiteIsGone: Boolean,
blackOnGame: Boolean,
blackIsGone: Boolean) {
def onGame(color: Color) = color.fold(whiteOnGame, blackOnGame)
def isGone(color: Color) = color.fold(whiteIsGone, blackIsGone)
}
package round {

View file

@ -1232,9 +1232,6 @@ div.negotiation .button,
div.force_resign_zone .button {
display: inline-block;
}
div.force_resign_zone {
display: none;
}
div.separator {
margin: 10px 0;
border-bottom: 1px solid #ddd;

View file

@ -54,9 +54,14 @@ function getPlayer(data, color) {
}
function setOnGame(data, color, onGame) {
getPlayer(data, color).onGame = onGame;
if (onGame) setIsGone(data, color, false);
}
function setIsGone(data, color, isGone) {
var player = getPlayer(data, color);
player.onGame = onGame;
if (onGame && player.user) player.user.online = true;
player.isGone = isGone;
if (!isGone && player.user) player.user.online = true;
}
function nbMoves(data, color) {
@ -77,5 +82,6 @@ module.exports = {
getPlayer: getPlayer,
parsePossibleMoves: parsePossibleMoves,
nbMoves: nbMoves,
setOnGame: setOnGame
setOnGame: setOnGame,
setIsGone: setIsGone
};

View file

@ -81,7 +81,7 @@ module.exports = function(send, ctrl) {
},
gone: function(isGone) {
if (!ctrl.data.opponent.ai) {
round.setOnGame(ctrl.data, ctrl.data.opponent.color, !isGone);
round.setIsGone(ctrl.data, ctrl.data.opponent.color, isGone);
m.redraw();
}
},

View file

@ -12,7 +12,7 @@ module.exports = {
}, m('span[data-icon=' + icon + ']')) : null;
},
forceResign: function(ctrl) {
if (!ctrl.data.opponent.ai && !ctrl.data.opponent.onGame && round.resignable(ctrl.data))
if (!ctrl.data.opponent.ai && ctrl.data.opponent.isGone && round.resignable(ctrl.data))
return m('div.force_resign_zone', [
ctrl.trans('theOtherPlayerHasLeftTheGameYouCanForceResignationOrWaitForHim'),
m('br'),