working POC of server-side eval cache
parent
ecb4f910f6
commit
02202c75ab
|
@ -173,5 +173,4 @@ object Env {
|
||||||
def coach = lila.coach.Env.current
|
def coach = lila.coach.Env.current
|
||||||
def pool = lila.pool.Env.current
|
def pool = lila.pool.Env.current
|
||||||
def practice = lila.practice.Env.current
|
def practice = lila.practice.Env.current
|
||||||
def evalCache = lila.evalCache.Env.current
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -542,7 +542,7 @@ challenge {
|
||||||
uid.timeout = 7 seconds
|
uid.timeout = 7 seconds
|
||||||
max_playing = ${setup.max_playing}
|
max_playing = ${setup.max_playing}
|
||||||
}
|
}
|
||||||
eval_cache {
|
evalCache {
|
||||||
collection.eval_cache = eval_cache
|
collection.eval_cache = eval_cache
|
||||||
}
|
}
|
||||||
study {
|
study {
|
||||||
|
|
|
@ -4,6 +4,8 @@ import scala.concurrent.duration._
|
||||||
|
|
||||||
import chess.format.{ FEN, Uci }
|
import chess.format.{ FEN, Uci }
|
||||||
import lila.db.dsl._
|
import lila.db.dsl._
|
||||||
|
import lila.socket.Handler.Controller
|
||||||
|
import lila.user.User
|
||||||
|
|
||||||
final class EvalCacheApi(coll: Coll) {
|
final class EvalCacheApi(coll: Coll) {
|
||||||
|
|
||||||
|
@ -14,6 +16,15 @@ final class EvalCacheApi(coll: Coll) {
|
||||||
|
|
||||||
def put(candidate: Input.Candidate): Funit = candidate.input ?? put
|
def put(candidate: Input.Candidate): Funit = candidate.input ?? put
|
||||||
|
|
||||||
|
def socketHandler(user: Option[User]): Controller =
|
||||||
|
user.filter(canPut).fold(lila.socket.Handler.emptyController)(makeController)
|
||||||
|
|
||||||
|
private def canPut(user: User) = true
|
||||||
|
|
||||||
|
private def makeController(user: User): Controller = {
|
||||||
|
case ("evalPut", o) => EvalCacheParser.parsePut(user, o.pp).pp foreach put
|
||||||
|
}
|
||||||
|
|
||||||
private def getEval(id: Id): Fu[Option[Eval]] = getEntry(id) map {
|
private def getEval(id: Id): Fu[Option[Eval]] = getEntry(id) map {
|
||||||
_.flatMap(_.bestEval)
|
_.flatMap(_.bestEval)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,22 +6,12 @@ import play.api.libs.json.JsObject
|
||||||
import chess.format.Uci
|
import chess.format.Uci
|
||||||
import EvalCacheEntry._
|
import EvalCacheEntry._
|
||||||
import lila.common.PimpedJson._
|
import lila.common.PimpedJson._
|
||||||
import lila.socket.Handler.Controller
|
|
||||||
import lila.tree.Eval._
|
import lila.tree.Eval._
|
||||||
import lila.user.User
|
import lila.user.User
|
||||||
|
|
||||||
final class SocketHandler(api: EvalCacheApi) {
|
private object EvalCacheParser {
|
||||||
|
|
||||||
def controller(user: User): Controller =
|
def parsePut(user: User, o: JsObject): Option[Input.Candidate] = for {
|
||||||
if (canPut(user)) makeController(user)
|
|
||||||
else lila.socket.Handler.emptyController
|
|
||||||
|
|
||||||
private def makeController(user: User): Controller = {
|
|
||||||
|
|
||||||
case ("evalPut", o) => parsePut(user, o) foreach api.put
|
|
||||||
}
|
|
||||||
|
|
||||||
private def parsePut(user: User, o: JsObject): Option[Input.Candidate] = for {
|
|
||||||
d <- o obj "d"
|
d <- o obj "d"
|
||||||
variant = chess.variant.Variant orDefault ~d.str("variant")
|
variant = chess.variant.Variant orDefault ~d.str("variant")
|
||||||
if variant.standard
|
if variant.standard
|
||||||
|
@ -40,7 +30,7 @@ final class SocketHandler(api: EvalCacheApi) {
|
||||||
date = DateTime.now))
|
date = DateTime.now))
|
||||||
|
|
||||||
private def parsePv(d: JsObject): Option[Pv] = for {
|
private def parsePv(d: JsObject): Option[Pv] = for {
|
||||||
movesStr <- d str "pv"
|
movesStr <- d str "moves"
|
||||||
moves <- movesStr.split(' ').take(EvalCacheEntry.MAX_PV_SIZE).toList.foldLeft(List.empty[Uci].some) {
|
moves <- movesStr.split(' ').take(EvalCacheEntry.MAX_PV_SIZE).toList.foldLeft(List.empty[Uci].some) {
|
||||||
case (Some(ucis), str) => Uci(str) map (_ :: ucis)
|
case (Some(ucis), str) => Uci(str) map (_ :: ucis)
|
||||||
case _ => None
|
case _ => None
|
||||||
|
@ -49,6 +39,4 @@ final class SocketHandler(api: EvalCacheApi) {
|
||||||
mate = d int "mate" map Mate.apply
|
mate = d int "mate" map Mate.apply
|
||||||
score <- cp.map(Score.cp) orElse mate.map(Score.mate)
|
score <- cp.map(Score.cp) orElse mate.map(Score.mate)
|
||||||
} yield Pv(score, moves)
|
} yield Pv(score, moves)
|
||||||
|
|
||||||
private def canPut(user: User) = true
|
|
||||||
}
|
}
|
|
@ -18,6 +18,7 @@ final class Env(
|
||||||
lightUserApi: lila.user.LightUserApi,
|
lightUserApi: lila.user.LightUserApi,
|
||||||
gamePgnDump: lila.game.PgnDump,
|
gamePgnDump: lila.game.PgnDump,
|
||||||
importer: lila.importer.Importer,
|
importer: lila.importer.Importer,
|
||||||
|
evalCache: lila.evalCache.EvalCacheApi,
|
||||||
system: ActorSystem,
|
system: ActorSystem,
|
||||||
hub: lila.hub.Env,
|
hub: lila.hub.Env,
|
||||||
db: lila.db.Env) {
|
db: lila.db.Env) {
|
||||||
|
@ -57,7 +58,8 @@ final class Env(
|
||||||
socketHub = socketHub,
|
socketHub = socketHub,
|
||||||
chat = hub.actor.chat,
|
chat = hub.actor.chat,
|
||||||
destCache = destCache,
|
destCache = destCache,
|
||||||
api = api)
|
api = api,
|
||||||
|
evalCache = evalCache)
|
||||||
|
|
||||||
lazy val studyRepo = new StudyRepo(coll = db(CollectionStudy))
|
lazy val studyRepo = new StudyRepo(coll = db(CollectionStudy))
|
||||||
lazy val chapterRepo = new ChapterRepo(coll = db(CollectionChapter))
|
lazy val chapterRepo = new ChapterRepo(coll = db(CollectionChapter))
|
||||||
|
@ -129,6 +131,7 @@ object Env {
|
||||||
lightUserApi = lila.user.Env.current.lightUserApi,
|
lightUserApi = lila.user.Env.current.lightUserApi,
|
||||||
gamePgnDump = lila.game.Env.current.pgnDump,
|
gamePgnDump = lila.game.Env.current.pgnDump,
|
||||||
importer = lila.importer.Env.current.importer,
|
importer = lila.importer.Env.current.importer,
|
||||||
|
evalCache = lila.evalCache.Env.current.api,
|
||||||
system = lila.common.PlayApp.system,
|
system = lila.common.PlayApp.system,
|
||||||
hub = lila.hub.Env.current,
|
hub = lila.hub.Env.current,
|
||||||
db = lila.db.Env.current)
|
db = lila.db.Env.current)
|
||||||
|
|
|
@ -23,7 +23,8 @@ private[study] final class SocketHandler(
|
||||||
socketHub: ActorRef,
|
socketHub: ActorRef,
|
||||||
chat: ActorSelection,
|
chat: ActorSelection,
|
||||||
destCache: LoadingCache[AnaDests.Ref, AnaDests],
|
destCache: LoadingCache[AnaDests.Ref, AnaDests],
|
||||||
api: StudyApi) {
|
api: StudyApi,
|
||||||
|
evalCache: lila.evalCache.EvalCacheApi) {
|
||||||
|
|
||||||
import Handler.AnaRateLimit
|
import Handler.AnaRateLimit
|
||||||
import JsonView.shapeReader
|
import JsonView.shapeReader
|
||||||
|
@ -40,7 +41,8 @@ private[study] final class SocketHandler(
|
||||||
studyId: Study.Id,
|
studyId: Study.Id,
|
||||||
uid: Uid,
|
uid: Uid,
|
||||||
member: Socket.Member,
|
member: Socket.Member,
|
||||||
owner: Boolean): Handler.Controller = ({
|
owner: Boolean,
|
||||||
|
user: Option[User]): Handler.Controller = ({
|
||||||
case ("p", o) => o int "v" foreach { v =>
|
case ("p", o) => o int "v" foreach { v =>
|
||||||
socket ! PingVersion(uid.value, v)
|
socket ! PingVersion(uid.value, v)
|
||||||
}
|
}
|
||||||
|
@ -233,7 +235,7 @@ private[study] final class SocketHandler(
|
||||||
byUserId <- member.userId
|
byUserId <- member.userId
|
||||||
v <- (o \ "d" \ "liked").asOpt[Boolean]
|
v <- (o \ "d" \ "liked").asOpt[Boolean]
|
||||||
} api.like(studyId, byUserId, v, socket, uid)
|
} api.like(studyId, byUserId, v, socket, uid)
|
||||||
}: Handler.Controller) orElse lila.chat.Socket.in(
|
}: Handler.Controller) orElse evalCache.socketHandler(user) orElse lila.chat.Socket.in(
|
||||||
chatId = studyId.value,
|
chatId = studyId.value,
|
||||||
member = member,
|
member = member,
|
||||||
socket = socket,
|
socket = socket,
|
||||||
|
@ -264,7 +266,7 @@ private[study] final class SocketHandler(
|
||||||
join = Socket.Join(uid = uid, userId = user.map(_.id), troll = user.??(_.troll), owner = owner)
|
join = Socket.Join(uid = uid, userId = user.map(_.id), troll = user.??(_.troll), owner = owner)
|
||||||
handler ← Handler(hub, socket, uid.value, join) {
|
handler ← Handler(hub, socket, uid.value, join) {
|
||||||
case Socket.Connected(enum, member) =>
|
case Socket.Connected(enum, member) =>
|
||||||
(controller(socket, studyId, uid, member, owner = owner), enum, member)
|
(controller(socket, studyId, uid, member, owner = owner, user = user), enum, member)
|
||||||
}
|
}
|
||||||
} yield handler.some
|
} yield handler.some
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,7 +240,8 @@ object ApplicationBuild extends Build {
|
||||||
libraryDependencies ++= provided(play.api, reactivemongo.driver)
|
libraryDependencies ++= provided(play.api, reactivemongo.driver)
|
||||||
)
|
)
|
||||||
|
|
||||||
lazy val study = project("study", Seq(common, db, hub, socket, game, round, importer, notifyModule, relation)).settings(
|
lazy val study = project("study", Seq(
|
||||||
|
common, db, hub, socket, game, round, importer, notifyModule, relation, evalCache)).settings(
|
||||||
libraryDependencies ++= provided(play.api, reactivemongo.driver)
|
libraryDependencies ++= provided(play.api, reactivemongo.driver)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -171,6 +171,7 @@ module.exports = function(data, ctrl, tagTypes, practiceData) {
|
||||||
// var evalPutMinNodes = 5e6;
|
// var evalPutMinNodes = 5e6;
|
||||||
var evalPutMinDepth = 16;
|
var evalPutMinDepth = 16;
|
||||||
var evalPutMinNodes = 1e6;
|
var evalPutMinNodes = 1e6;
|
||||||
|
var evalPutMaxMoves = 8;
|
||||||
var onCeval = throttle(1000, false, function(eval) {
|
var onCeval = throttle(1000, false, function(eval) {
|
||||||
if (isStandard() && eval.depth >= evalPutMinDepth && eval.nodes > evalPutMinNodes) send("evalPut", {
|
if (isStandard() && eval.depth >= evalPutMinDepth && eval.nodes > evalPutMinNodes) send("evalPut", {
|
||||||
fen: eval.fen,
|
fen: eval.fen,
|
||||||
|
@ -181,7 +182,7 @@ module.exports = function(data, ctrl, tagTypes, practiceData) {
|
||||||
return {
|
return {
|
||||||
cp: pv.cp,
|
cp: pv.cp,
|
||||||
mate: pv.mate,
|
mate: pv.mate,
|
||||||
moves: pv.pv
|
moves: pv.pv.split(' ').slice(0, evalPutMaxMoves).join(' ')
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue