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