basic eval cache trust system

This commit is contained in:
Thibault Duplessis 2017-01-31 15:17:07 +01:00
parent 02202c75ab
commit 39bef980da
5 changed files with 64 additions and 15 deletions

View file

@ -10,7 +10,8 @@ final class Env(
private val CollectionEvalCache = config getString "collection.eval_cache"
lazy val api = new EvalCacheApi(
coll = db(CollectionEvalCache))
coll = db(CollectionEvalCache),
truster = new Truster)
}
object Env {

View file

@ -1,5 +1,6 @@
package lila.evalCache
import org.joda.time.DateTime
import scala.concurrent.duration._
import chess.format.{ FEN, Uci }
@ -7,22 +8,28 @@ import lila.db.dsl._
import lila.socket.Handler.Controller
import lila.user.User
final class EvalCacheApi(coll: Coll) {
final class EvalCacheApi(
coll: Coll,
truster: Truster) {
import EvalCacheEntry._
import BSONHandlers._
def getEval(fen: String, multiPv: Int): Fu[Option[Eval]] = Id(fen, multiPv) ?? getEval
def put(candidate: Input.Candidate): Funit = candidate.input ?? put
def put(trustedUser: TrustedUser, candidate: Input.Candidate): Funit =
candidate.input ?? { put(trustedUser, _) }
def socketHandler(user: Option[User]): Controller =
user.filter(canPut).fold(lila.socket.Handler.emptyController)(makeController)
def socketHandler(userOption: Option[User]): Controller = {
userOption.fold(lila.socket.Handler.emptyController) { user =>
val trust = truster(user)
if (trust.isTooLow) lila.socket.Handler.emptyController
else makeController(TrustedUser(trust, user))
}
}
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 makeController(trustedUser: TrustedUser): Controller = {
case ("evalPut", o) => EvalCacheParser.parsePut(trustedUser.user, o) foreach { put(trustedUser, _) }
}
private def getEval(id: Id): Fu[Option[Eval]] = getEntry(id) map {
@ -31,10 +38,11 @@ final class EvalCacheApi(coll: Coll) {
private def getEntry(id: Id): Fu[Option[EvalCacheEntry]] = coll.find($id(id)).one[EvalCacheEntry]
private def put(input: Input): Funit =
private def put(trustedUser: TrustedUser, input: Input): Funit = {
getEntry(input.id) map {
_.fold(input entry Trust(1))(_ add input.eval)
_.fold(input entry trustedUser.trust)(_ add input.trusted(trustedUser.trust))
} flatMap { entry =>
coll.update($id(entry.id), entry, upsert = true).void
}
}
}

View file

@ -19,7 +19,7 @@ case class EvalCacheEntry(
def bestEval: Option[Eval] = evals.headOption.map(_.eval)
def add(eval: Eval) = copy(evals = TrustedEval(Trust(1), eval) :: evals)
def add(trustedEval: TrustedEval) = copy(evals = trustedEval :: evals)
}
object EvalCacheEntry {
@ -63,7 +63,11 @@ object EvalCacheEntry {
def truncate = copy(value = NonEmptyList.nel(value.head, value.tail.take(MAX_PV_SIZE - 1)))
}
case class Trust(value: Double) extends AnyVal
case class Trust(value: Double) extends AnyVal {
def isTooLow = value <= 0
}
case class TrustedUser(trust: Trust, user: lila.user.User)
final class MultiPv private (val value: Int) extends AnyVal
@ -90,7 +94,8 @@ object EvalCacheEntry {
}
case class Input(id: Id, eval: Eval) {
def entry(trust: Trust) = EvalCacheEntry(id, List(TrustedEval(trust, eval)))
def trusted(trust: Trust) = TrustedEval(trust, eval)
def entry(trust: Trust) = EvalCacheEntry(id, List(trusted(trust)))
}
object Input {

View file

@ -0,0 +1,35 @@
package lila.evalCache
import org.joda.time.{ DateTime, Months }
import lila.security.Granter
import lila.user.User
private final class Truster {
import EvalCacheEntry.Trust
private val LOWER = Trust(-9999)
private val HIGHER = Trust(9999)
def apply(user: User): Trust =
if (user.createdAt isBefore DateTime.now.minusDays(14)) LOWER
else if (user.lameOrTroll) LOWER
else if (Granter(_.SeeReport)(user)) HIGHER
else Trust {
1 +
seniorityBonus(user) +
patronBonus(user) +
titleBonus(user) +
nbGamesBonus(user)
}
private def seniorityBonus(user: User) =
Months.monthsBetween(user.createdAt, DateTime.now).getMonths atMost 10
private def patronBonus(user: User) = (~user.planMonths * 5) atMost 20
private def titleBonus(user: User) = user.hasTitle ?? 20
private def nbGamesBonus(user: User) = (user.count.game / 1000) atMost 5
}

View file

@ -255,7 +255,7 @@ object ApplicationBuild extends Build {
libraryDependencies ++= provided(play.api, reactivemongo.driver)
)
lazy val evalCache = project("evalCache", Seq(common, db, user, socket, tree)).settings(
lazy val evalCache = project("evalCache", Seq(common, db, user, security, socket, tree)).settings(
libraryDependencies ++= provided(play.api, reactivemongo.driver)
)