more puzzle monitoring

puzzle
Thibault Duplessis 2020-12-18 10:26:05 +01:00
parent d30c04c95c
commit 1a0ad20efa
6 changed files with 41 additions and 18 deletions

View File

@ -20,6 +20,16 @@ object Chronometer {
this
}
def mon(path: lila.mon.TimerPath) = {
path(lila.mon).record(nanos).unit
this
}
def monValue(path: A => lila.mon.TimerPath) = {
path(result)(lila.mon).record(nanos).unit
this
}
def pp: A = {
println(s"chrono $showDuration")
result
@ -45,16 +55,12 @@ object Chronometer {
}
def mon(path: lila.mon.TimerPath) = {
lap dforeach { l =>
path(lila.mon).record(l.nanos).unit
}
lap dforeach { _.mon(path).unit }
this
}
def monValue(path: A => lila.mon.TimerPath) = {
lap dforeach { l =>
path(l.result)(lila.mon).record(l.nanos).unit
}
lap dforeach { _.monValue(path).unit }
this
}
@ -67,6 +73,11 @@ object Chronometer {
def pp(msg: String): Fu[A] = lap.dmap(_ pp msg)
def ppIfGt(msg: String, duration: FiniteDuration): Fu[A] = lap.dmap(_.ppIfGt(msg, duration))
def tap(f: Lap[A] => Unit) = {
lap dforeach f
this
}
def result = lap.dmap(_.result)
}

View File

@ -420,13 +420,15 @@ object mon {
object puzzle {
object selector {
object user {
def puzzle(theme: String, retries: Int) =
timer("puzzle.selector.user.puzzle").withTags(Map("theme" -> theme, "retries" -> retries))
def puzzle(theme: String, retries: Int, vote: Int) =
timer("puzzle.selector.user.puzzle").withTags(
Map("theme" -> theme, "retries" -> retries, "vote" -> vote)
)
def batch(nb: Int) = timer("puzzle.selector.user.batch").withTag("nb", nb)
}
object anon {
val puzzle = timer("puzzle.selector.anon.puzzle").withoutTags()
def batch(nb: Int) = timer("puzzle.selector.anon.batch").withTag("nb", nb)
def puzzle(vote: Int) = timer("puzzle.selector.anon.puzzle").withTag("vote", vote)
def batch(nb: Int) = timer("puzzle.selector.anon.batch").withTag("nb", nb)
}
def nextPuzzleResult(theme: String, difficulty: String, position: Int, result: String) =
timer("puzzle.selector.user.puzzle").withTags(

View File

@ -25,6 +25,7 @@ private[puzzle] object BsonHandlers {
line <- lineStr.split(' ').toList.flatMap(Uci.Move.apply).toNel.toTry("Empty move list?!")
glicko <- r.getAsTry[Glicko](glicko)
plays <- r.getAsTry[Int](plays)
vote <- r.getAsTry[Int](vote)
themes <- r.getAsTry[Set[PuzzleTheme.Key]](themes)
} yield Puzzle(
id = id,
@ -33,6 +34,7 @@ private[puzzle] object BsonHandlers {
line = line,
glicko = glicko,
plays = plays,
vote = vote,
themes = themes
)
}

View File

@ -12,6 +12,7 @@ case class Puzzle(
line: NonEmptyList[Uci.Move],
glicko: Glicko,
plays: Int,
vote: Int,
themes: Set[PuzzleTheme.Key]
) {
// ply after "initial move" when we start solving

View File

@ -15,13 +15,18 @@ final class PuzzleAnon(colls: PuzzleColls, cacheApi: CacheApi, pathApi: PuzzlePa
def getOneFor(theme: PuzzleTheme.Key): Fu[Option[Puzzle]] = {
pool get theme map ThreadLocalRandom.oneOf
}.mon(_.puzzle.selector.anon.puzzle)
}.chronometer.tap { lap =>
lap.result.foreach { puzzle =>
lap.mon(_.puzzle.selector.anon.puzzle(puzzle.vote))
}
}.result
def getBatchFor(nb: Int): Fu[Vector[Puzzle]] = {
pool get PuzzleTheme.mix.key map (_ take nb)
}.mon(_.puzzle.selector.anon.batch(nb))
private val poolSize = 60
private val poolSize = 80
private val minPathLength = 10
private val pool =
cacheApi[PuzzleTheme.Key, Vector[Puzzle]](initialCapacity = 64, name = "puzzle.byTheme.anon") {
@ -29,18 +34,18 @@ final class PuzzleAnon(colls: PuzzleColls, cacheApi: CacheApi, pathApi: PuzzlePa
.buildAsyncFuture { theme =>
pathApi countPuzzlesByTheme theme flatMap { count =>
val tier =
if (count > 4000) PuzzleTier.Top
else if (count > 1500) PuzzleTier.Good
if (count > 5000) PuzzleTier.Top
else if (count > 2000) PuzzleTier.Good
else PuzzleTier.All
val ratingRange: Range =
if (count > 9000) 1200 to 1600
else if (count > 5000) 1000 to 1800
if (count > 9000) 1300 to 1600
else if (count > 5000) 1100 to 1800
else 0 to 9999
colls.path {
_.aggregateList(poolSize) { framework =>
import framework._
Match(pathApi.select(theme, tier, ratingRange)) -> List(
Sample(3),
Sample(poolSize / minPathLength),
Project($doc("puzzleId" -> "$ids", "_id" -> false)),
Unwind("puzzleId"),
Sample(poolSize),

View File

@ -73,7 +73,9 @@ final class PuzzleSessionApi(
case PuzzleFound(puzzle) => fuccess(puzzle)
}
}
.mon(_.puzzle.selector.user.puzzle(theme = theme.value, retries = retries))
.monValue { puzzle =>
_.puzzle.selector.user.puzzle(theme = theme.value, retries = retries, vote = puzzle.vote)
}
private def nextPuzzleResult(user: User, session: PuzzleSession): Fu[NextPuzzleResult] =
colls