explicit reflective calls, upgrade scalalib and scalachess
parent
f1d9188497
commit
089b807c03
|
@ -19,7 +19,7 @@ trait NumberHelper { self: I18nHelper =>
|
|||
|
||||
def showMillis(millis: Int)(implicit ctx: UserContext) = formatter.format((millis / 100).toDouble / 10)
|
||||
|
||||
implicit def richInt(number: Int) = new {
|
||||
implicit final class RichInt(number: Int) {
|
||||
def localize(implicit ctx: UserContext): String = formatter format number
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,32 +5,34 @@ import lila.common.paginator.Paginator
|
|||
|
||||
trait PaginatorHelper {
|
||||
|
||||
implicit def toRichPager[A](pager: Paginator[A]) = new {
|
||||
|
||||
def sliding(length: Int, showPost: Boolean = true): List[Option[Int]] = {
|
||||
val fromPage = 1 max (pager.currentPage - length)
|
||||
val toPage = pager.nbPages min (pager.currentPage + length)
|
||||
val pre = fromPage match {
|
||||
case 1 => Nil
|
||||
case 2 => List(1.some)
|
||||
case _ => List(1.some, none)
|
||||
}
|
||||
val post = toPage match {
|
||||
case x if x == pager.nbPages => Nil
|
||||
case x if x == pager.nbPages - 1 => List(pager.nbPages.some)
|
||||
case _ if showPost => List(none, pager.nbPages.some)
|
||||
case _ => List(none)
|
||||
}
|
||||
pre ::: (fromPage to toPage).view.map(some).toList ::: post
|
||||
}
|
||||
|
||||
def firstIndex: Int =
|
||||
(pager.maxPerPage.value * (pager.currentPage - 1) + 1) min pager.nbResults
|
||||
|
||||
def lastIndex: Int =
|
||||
(firstIndex + pageNbResults - 1) max 0
|
||||
|
||||
def pageNbResults =
|
||||
pager.currentPageResults.size
|
||||
}
|
||||
implicit def toRichPager[A](pager: Paginator[A]): RichPager = new RichPager(pager)
|
||||
}
|
||||
|
||||
final class RichPager(pager: Paginator[_]) {
|
||||
|
||||
def sliding(length: Int, showPost: Boolean = true): List[Option[Int]] = {
|
||||
val fromPage = 1 max (pager.currentPage - length)
|
||||
val toPage = pager.nbPages min (pager.currentPage + length)
|
||||
val pre = fromPage match {
|
||||
case 1 => Nil
|
||||
case 2 => List(1.some)
|
||||
case _ => List(1.some, none)
|
||||
}
|
||||
val post = toPage match {
|
||||
case x if x == pager.nbPages => Nil
|
||||
case x if x == pager.nbPages - 1 => List(pager.nbPages.some)
|
||||
case _ if showPost => List(none, pager.nbPages.some)
|
||||
case _ => List(none)
|
||||
}
|
||||
pre ::: (fromPage to toPage).view.map(some).toList ::: post
|
||||
}
|
||||
|
||||
def firstIndex: Int =
|
||||
(pager.maxPerPage.value * (pager.currentPage - 1) + 1) min pager.nbResults
|
||||
|
||||
def lastIndex: Int =
|
||||
(firstIndex + pageNbResults - 1) max 0
|
||||
|
||||
def pageNbResults =
|
||||
pager.currentPageResults.size
|
||||
}
|
||||
|
|
|
@ -16,11 +16,6 @@ trait StringHelper { self: NumberHelper =>
|
|||
|
||||
def urlencode(str: String): String = java.net.URLEncoder.encode(str, "US-ASCII")
|
||||
|
||||
implicit def lilaRichString(str: String) = new {
|
||||
def active(other: String, one: String = "active") = if (str == other) one else ""
|
||||
def activeO(other: String, one: String = "active") = if (str == other) Some(one) else None
|
||||
}
|
||||
|
||||
def when(cond: Boolean, str: String) = cond ?? str
|
||||
|
||||
private val NumberFirstRegex = """(\d++)\s(.+)""".r
|
||||
|
@ -58,4 +53,11 @@ trait StringHelper { self: NumberHelper =>
|
|||
frag(separator, f)
|
||||
}
|
||||
}
|
||||
|
||||
implicit def lilaRichString(str: String): LilaRichString = new LilaRichString(str)
|
||||
}
|
||||
|
||||
final class LilaRichString(val str: String) extends AnyVal {
|
||||
def active(other: String, one: String = "active") = if (str == other) one else ""
|
||||
def activeO(other: String, one: String = "active") = if (str == other) Some(one) else None
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package views.html.base
|
|||
|
||||
import lila.common.String.html.safeJsonValue
|
||||
import play.api.libs.json.Json
|
||||
import scala.language.reflectiveCalls
|
||||
|
||||
import lila.api.Context
|
||||
import lila.app.templating.Environment._
|
||||
|
|
|
@ -27,6 +27,7 @@ object Captcha {
|
|||
|
||||
val failMessage = "captcha.fail"
|
||||
|
||||
import scala.language.reflectiveCalls
|
||||
def isFailed(form: Form.FormLike) =
|
||||
form.errors.exists { _.messages has failMessage }
|
||||
}
|
||||
|
|
|
@ -437,16 +437,17 @@ object mon {
|
|||
}
|
||||
object fishnet {
|
||||
object client {
|
||||
def result(client: String) = new {
|
||||
private val c = counter("fishnet.client.result")
|
||||
private def apply(r: String): Counter = c.withTags(Map("client" -> client, "result" -> r))
|
||||
val success = apply("success")
|
||||
val failure = apply("failure")
|
||||
val weak = apply("weak")
|
||||
val timeout = apply("timeout")
|
||||
val notFound = apply("notFound")
|
||||
val notAcquired = apply("notAcquired")
|
||||
val abort = apply("abort")
|
||||
object result {
|
||||
private val c = counter("fishnet.client.result")
|
||||
private def apply(r: String)(client: String): Counter =
|
||||
c.withTags(Map("client" -> client, "result" -> r))
|
||||
val success = apply("success") _
|
||||
val failure = apply("failure") _
|
||||
val weak = apply("weak") _
|
||||
val timeout = apply("timeout") _
|
||||
val notFound = apply("notFound") _
|
||||
val notAcquired = apply("notAcquired") _
|
||||
val abort = apply("abort") _
|
||||
}
|
||||
def status(enabled: Boolean) = gauge("fishnet.client.status").withTag("enabled", enabled)
|
||||
def version(v: String) = gauge("fishnet.client.version").withTag("version", v)
|
||||
|
@ -461,19 +462,21 @@ object mon {
|
|||
val forUser = gauge("fishnet.work.forUser").withoutTags
|
||||
}
|
||||
object analysis {
|
||||
def by(client: String) = new {
|
||||
val hash = histogram("fishnet.analysis.hash").withTag("client", client)
|
||||
val threads = gauge("fishnet.analysis.threads").withTag("client", client)
|
||||
val movetime = histogram("fishnet.analysis.movetime").withTag("client", client)
|
||||
val node = histogram("fishnet.analysis.node").withTag("client", client)
|
||||
val nps = histogram("fishnet.analysis.nps").withTag("client", client)
|
||||
val depth = histogram("fishnet.analysis.depth").withTag("client", client)
|
||||
val pvSize = histogram("fishnet.analysis.pvSize").withTag("client", client)
|
||||
def pv(isLong: Boolean) =
|
||||
object by {
|
||||
def hash(client: String) = histogram("fishnet.analysis.hash").withTag("client", client)
|
||||
def threads(client: String) = gauge("fishnet.analysis.threads").withTag("client", client)
|
||||
def movetime(client: String) = histogram("fishnet.analysis.movetime").withTag("client", client)
|
||||
def node(client: String) = histogram("fishnet.analysis.node").withTag("client", client)
|
||||
def nps(client: String) = histogram("fishnet.analysis.nps").withTag("client", client)
|
||||
def depth(client: String) = histogram("fishnet.analysis.depth").withTag("client", client)
|
||||
def pvSize(client: String) = histogram("fishnet.analysis.pvSize").withTag("client", client)
|
||||
def pv(client: String, isLong: Boolean) =
|
||||
counter("fishnet.analysis.pvs").withTags(Map("client" -> client, "long" -> isLong))
|
||||
val totalMeganode = counter("fishnet.analysis.total.meganode").withTag("client", client)
|
||||
val totalSecond = counter("fishnet.analysis.total.second").withTag("client", client)
|
||||
val totalPosition = counter("fishnet.analysis.total.position").withTag("client", client)
|
||||
def totalMeganode(client: String) =
|
||||
counter("fishnet.analysis.total.meganode").withTag("client", client)
|
||||
def totalSecond(client: String) = counter("fishnet.analysis.total.second").withTag("client", client)
|
||||
def totalPosition(client: String) =
|
||||
counter("fishnet.analysis.total.position").withTag("client", client)
|
||||
}
|
||||
val post = timer("fishnet.analysis.post").withoutTags
|
||||
def requestCount(tpe: String) = counter("fishnet.analysis.request").withTag("type", tpe)
|
||||
|
|
|
@ -6,6 +6,8 @@ final private class Monitor(
|
|||
repo: FishnetRepo
|
||||
)(implicit system: akka.actor.ActorSystem) {
|
||||
|
||||
private val monBy = lila.mon.fishnet.analysis.by
|
||||
|
||||
private def sumOf[A](items: List[A])(f: A => Option[Int]) = items.foldLeft(0) {
|
||||
case (acc, a) => acc + f(a).getOrElse(0)
|
||||
}
|
||||
|
@ -17,17 +19,19 @@ final private class Monitor(
|
|||
) = {
|
||||
Monitor.success(work, client)
|
||||
|
||||
val monitor = lila.mon.fishnet.analysis by client.userId.value
|
||||
val threads = result.stockfish.options.threadsInt
|
||||
val userId = client.userId.value
|
||||
|
||||
result.stockfish.options.hashInt foreach { monitor.hash.record(_) }
|
||||
result.stockfish.options.threadsInt foreach { monitor.threads.update(_) }
|
||||
result.stockfish.options.hashInt foreach { monBy.hash(userId).record(_) }
|
||||
result.stockfish.options.threadsInt foreach { monBy.threads(userId).update(_) }
|
||||
|
||||
monitor.totalSecond.increment(sumOf(result.evaluations)(_.time) * threads.|(1) / 1000)
|
||||
monitor.totalMeganode.increment(sumOf(result.evaluations) { eval =>
|
||||
eval.nodes ifFalse eval.mateFound
|
||||
} / 1000000)
|
||||
monitor.totalPosition.increment(result.evaluations.size)
|
||||
monBy.totalSecond(userId).increment(sumOf(result.evaluations)(_.time) * threads.|(1) / 1000)
|
||||
monBy
|
||||
.totalMeganode(userId)
|
||||
.increment(sumOf(result.evaluations) { eval =>
|
||||
eval.nodes ifFalse eval.mateFound
|
||||
} / 1000000)
|
||||
monBy.totalPosition(userId).increment(result.evaluations.size)
|
||||
|
||||
val metaMovesSample = sample(result.evaluations.drop(6).filterNot(_.mateFound), 100)
|
||||
def avgOf(f: JsonApi.Request.Evaluation => Option[Int]): Option[Int] = {
|
||||
|
@ -39,17 +43,17 @@ final private class Monitor(
|
|||
}
|
||||
(nb > 0) option (sum / nb)
|
||||
}
|
||||
avgOf(_.time) foreach { monitor.movetime.record(_) }
|
||||
avgOf(_.nodes) foreach { monitor.node.record(_) }
|
||||
avgOf(_.cappedNps) foreach { monitor.nps.record(_) }
|
||||
avgOf(_.depth) foreach { monitor.depth.record(_) }
|
||||
avgOf(_.pv.size.some) foreach { monitor.pvSize.record(_) }
|
||||
avgOf(_.time) foreach { monBy.movetime(userId).record(_) }
|
||||
avgOf(_.nodes) foreach { monBy.node(userId).record(_) }
|
||||
avgOf(_.cappedNps) foreach { monBy.nps(userId).record(_) }
|
||||
avgOf(_.depth) foreach { monBy.depth(userId).record(_) }
|
||||
avgOf(_.pv.size.some) foreach { monBy.pvSize(userId).record(_) }
|
||||
|
||||
val significantPvSizes =
|
||||
result.evaluations.filterNot(_.mateFound).filterNot(_.deadDraw).map(_.pv.size)
|
||||
|
||||
monitor.pv(false).increment(significantPvSizes.count(_ < 3))
|
||||
monitor.pv(true).increment(significantPvSizes.count(_ >= 6))
|
||||
monBy.pv(userId, false).increment(significantPvSizes.count(_ < 3))
|
||||
monBy.pv(userId, true).increment(significantPvSizes.count(_ >= 6))
|
||||
}
|
||||
|
||||
private def sample[A](elems: List[A], n: Int) =
|
||||
|
@ -94,9 +98,11 @@ final private class Monitor(
|
|||
|
||||
object Monitor {
|
||||
|
||||
private val monResult = lila.mon.fishnet.client.result
|
||||
|
||||
private def success(work: Work, client: Client) = {
|
||||
|
||||
lila.mon.fishnet.client.result(client.userId.value).success.increment()
|
||||
monResult.success(client.userId.value).increment()
|
||||
|
||||
work.acquiredAt foreach { acquiredAt =>
|
||||
lila.mon.fishnet.queue.record {
|
||||
|
@ -107,31 +113,31 @@ object Monitor {
|
|||
|
||||
private[fishnet] def failure(work: Work, client: Client, e: Exception) = {
|
||||
logger.warn(s"Received invalid analysis ${work.id} for ${work.game.id} by ${client.fullId}", e)
|
||||
lila.mon.fishnet.client.result(client.userId.value).failure.increment()
|
||||
monResult.failure(client.userId.value).increment()
|
||||
}
|
||||
|
||||
private[fishnet] def weak(work: Work, client: Client, data: JsonApi.Request.CompleteAnalysis) = {
|
||||
logger.warn(
|
||||
s"Received weak analysis ${work.id} (nodes: ${~data.medianNodes}) for ${work.game.id} by ${client.fullId}"
|
||||
)
|
||||
lila.mon.fishnet.client.result(client.userId.value).weak.increment()
|
||||
monResult.weak(client.userId.value).increment()
|
||||
}
|
||||
|
||||
private[fishnet] def timeout(userId: Client.UserId) =
|
||||
lila.mon.fishnet.client.result(userId.value).timeout.increment()
|
||||
monResult.timeout(userId.value).increment()
|
||||
|
||||
private[fishnet] def abort(client: Client) =
|
||||
lila.mon.fishnet.client.result(client.userId.value).abort.increment()
|
||||
monResult.abort(client.userId.value).increment()
|
||||
|
||||
private[fishnet] def notFound(id: Work.Id, client: Client) = {
|
||||
logger.info(s"Received unknown analysis $id by ${client.fullId}")
|
||||
lila.mon.fishnet.client.result(client.userId.value).notFound.increment()
|
||||
monResult.notFound(client.userId.value).increment()
|
||||
}
|
||||
|
||||
private[fishnet] def notAcquired(work: Work, client: Client) = {
|
||||
logger.info(
|
||||
s"Received unacquired analysis ${work.id} for ${work.game.id} by ${client.fullId}. Work current tries: ${work.tries} acquired: ${work.acquired}"
|
||||
)
|
||||
lila.mon.fishnet.client.result(client.userId.value).notAcquired.increment()
|
||||
monResult.notAcquired(client.userId.value).increment()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import chess.{ Black, Clock, White }
|
|||
|
||||
import lila.common.Future
|
||||
import lila.game.{ Game, GameRepo, UciMemo }
|
||||
import ornicar.scalalib.Random.approximatly
|
||||
import ornicar.scalalib.Random.approximately
|
||||
|
||||
final class Player(
|
||||
redis: FishnetRedis,
|
||||
|
@ -40,7 +40,7 @@ final class Player(
|
|||
sleep = (delay * accel) atMost 500
|
||||
if sleep > 25
|
||||
millis = sleep * 10
|
||||
randomized = approximatly(0.5f)(millis)
|
||||
randomized = approximately(0.5f)(millis)
|
||||
divided = randomized / (if (g.turns > 9) 1 else 2)
|
||||
} yield divided.millis
|
||||
|
||||
|
|
|
@ -219,7 +219,7 @@ object BSONHandlers {
|
|||
}
|
||||
}
|
||||
|
||||
implicit val lightGameBSONHandler = new lila.db.BSONReadOnly[LightGame] {
|
||||
implicit object lightGameBSONHandler extends lila.db.BSONReadOnly[LightGame] {
|
||||
|
||||
import Game.{ BSONFields => F }
|
||||
import Player.playerBSONHandler
|
||||
|
|
|
@ -95,7 +95,7 @@ object Crosstable {
|
|||
val lastPlayed = "d"
|
||||
}
|
||||
|
||||
implicit private[game] val crosstableBSONHandler = new BSON[Crosstable] {
|
||||
implicit private[game] object crosstableBSONHandler extends BSON[Crosstable] {
|
||||
|
||||
import BSONFields._
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ trait CaptchedForm {
|
|||
def withCaptcha[A](form: Form[A]): Fu[(Form[A], Captcha)] =
|
||||
anyCaptcha map (form -> _)
|
||||
|
||||
import scala.language.reflectiveCalls
|
||||
def validateCaptcha(data: CaptchedData) =
|
||||
getCaptcha(data.gameId) awaitSeconds 2 valid data.move.trim.toLowerCase
|
||||
|
||||
|
|
|
@ -51,7 +51,6 @@ object BuildSettings {
|
|||
val compilerOptions = Seq(
|
||||
"-language:implicitConversions",
|
||||
"-language:postfixOps",
|
||||
"-language:reflectiveCalls", // #TODO remove me for perfs
|
||||
"-feature",
|
||||
"-unchecked",
|
||||
"-deprecation",
|
||||
|
|
|
@ -12,10 +12,10 @@ object Dependencies {
|
|||
}
|
||||
|
||||
val scalaz = "org.scalaz" %% "scalaz-core" % "7.2.29"
|
||||
val scalalib = "com.github.ornicar" %% "scalalib" % "6.7"
|
||||
val scalalib = "com.github.ornicar" %% "scalalib" % "6.8"
|
||||
val hasher = "com.roundeights" %% "hasher" % "1.2.1"
|
||||
val jodaTime = "joda-time" % "joda-time" % "2.10.5"
|
||||
val chess = "org.lichess" %% "scalachess" % "9.0.27"
|
||||
val chess = "org.lichess" %% "scalachess" % "9.1.0"
|
||||
val compression = "org.lichess" %% "compression" % "1.5"
|
||||
val maxmind = "com.sanoma.cda" %% "maxmind-geoip2-scala" % "1.3.1-THIB"
|
||||
val prismic = "io.prismic" %% "scala-kit" % "1.2.13-THIB213"
|
||||
|
@ -40,11 +40,9 @@ object Dependencies {
|
|||
val driver = "org.reactivemongo" %% "reactivemongo" % version
|
||||
val bson = "org.reactivemongo" %% "reactivemongo-bson-api" % version
|
||||
val stream = "org.reactivemongo" %% "reactivemongo-akkastream" % version
|
||||
// val native = "org.reactivemongo" % "reactivemongo-shaded-native" % s"$version-linux-x86-64" classifier "linux-x86_64"
|
||||
val native = "org.reactivemongo" % "reactivemongo-shaded-native" % s"$version-linux-x86-64"
|
||||
// #TODO remove compat
|
||||
val compat = "org.reactivemongo" %% "reactivemongo-bson-compat" % version
|
||||
def bundle = Seq(driver, bson, compat, stream)
|
||||
val native = "org.reactivemongo" % "reactivemongo-shaded-native" % s"$version-linux-x86-64"
|
||||
val compat = "org.reactivemongo" %% "reactivemongo-bson-compat" % version
|
||||
def bundle = Seq(driver, bson, compat, stream)
|
||||
}
|
||||
|
||||
object play {
|
||||
|
|
Loading…
Reference in New Issue