Skip to content

Commit 5700f74

Browse files
committed
make EvalCacheMulti easier to test
1 parent 509a840 commit 5700f74

File tree

4 files changed

+43
-40
lines changed

4 files changed

+43
-40
lines changed

src/main/scala/evalCache/EvalCacheApi.scala

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package lila.ws
22
package evalCache
33

4+
import org.apache.pekko.actor.typed.Scheduler
5+
import java.time.LocalDateTime
46
import cats.syntax.all.*
57
import chess.ErrorStr
68
import chess.format.Fen
@@ -10,19 +12,14 @@ import com.typesafe.scalalogging.Logger
1012
import play.api.libs.json.JsString
1113
import reactivemongo.api.bson.BSONDocument
1214

13-
import java.time.LocalDateTime
14-
1515
import lila.ws.ipc.ClientIn
1616
import lila.ws.ipc.ClientOut.{ EvalGet, EvalGetMulti, EvalPut }
1717

18-
final class EvalCacheApi(mongo: Mongo, settings: util.SettingStore)(using
19-
Executor,
20-
org.apache.pekko.actor.typed.Scheduler
21-
):
18+
final class EvalCacheApi(mongo: Mongo)(using Executor, Scheduler):
2219

2320
private val truster = wire[EvalCacheTruster]
2421
private val upgrade = wire[EvalCacheUpgrade]
25-
private val multi = EvalCacheMulti()
22+
private val multi = EvalCacheMulti.withMonitoring()
2623

2724
import EvalCacheEntry.*
2825
import EvalCacheBsonHandlers.given
Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,28 @@
11
package lila.ws
22
package evalCache
33

4+
import java.util.concurrent.ConcurrentHashMap
5+
import org.apache.pekko.actor.typed.Scheduler
46
import chess.format.Fen
57
import chess.variant.Variant
6-
7-
import java.util.concurrent.ConcurrentHashMap
8+
import scalalib.zeros.given
89

910
import lila.ws.ipc.ClientIn.EvalHitMulti
1011
import lila.ws.ipc.ClientOut.EvalGetMulti
1112
import lila.ws.util.ExpireCallbackMemo
13+
import lila.ws.util.ExpireMemo
1214

1315
/* Compared to EvalCacheUpgrade, accepts multiple positions per member,
1416
* only sends cp/mate
1517
*/
16-
final private class EvalCacheMulti(using
17-
ec: Executor,
18-
scheduler: org.apache.pekko.actor.typed.Scheduler
19-
):
18+
final private class EvalCacheMulti private (makeExpirableSris: (Sri => Unit) => ExpireMemo[Sri]):
2019
import EvalCacheMulti.*
2120
import EvalCacheUpgrade.{ EvalState, SriString }
2221

23-
private val members = ConcurrentHashMap[SriString, WatchingMember](4096)
24-
private val evals = ConcurrentHashMap[Id, EvalState](1024)
25-
private val expirableSris = ExpireCallbackMemo[Sri](scheduler, 1 minute, expire)
22+
private val members = ConcurrentHashMap[SriString, WatchingMember](4096)
23+
private val evals = ConcurrentHashMap[Id, EvalState](1024)
24+
private val expirableSris: ExpireMemo[Sri] = makeExpirableSris(expire)
2625

27-
private val upgradeMon = Monitor.evalCache.multi.upgrade
2826

2927
def register(sri: Sri, e: EvalGetMulti): Unit =
3028
members
@@ -41,22 +39,24 @@ final private class EvalCacheMulti(using
4139
expirableSris.put(sri)
4240

4341
def onEval(input: EvalCacheEntry.Input): Unit =
44-
Option(
42+
val sris = onEvalSrisToUpgrade(input)
43+
if sris.nonEmpty then
44+
val hit = EvalHitMulti:
45+
EvalCacheJsonHandlers.writeMultiHit(input.fen, input.eval)
46+
sris.foreach: sri =>
47+
Bus.publish(_.sri(sri), hit)
48+
upgradeMon.count.increment(sris.size)
49+
50+
private def onEvalSrisToUpgrade(input: EvalCacheEntry.Input): Set[Sri] =
51+
val newEval = Option(
4552
evals.computeIfPresent(
4653
input.id,
4754
(_, ev) =>
4855
if ev.depth >= input.eval.depth then ev
4956
else ev.copy(depth = input.eval.depth)
5057
)
5158
).filter(_.depth == input.eval.depth)
52-
.foreach: eval =>
53-
val sris = eval.sris.filter(_ != input.sri)
54-
if sris.nonEmpty then
55-
val hit = EvalHitMulti:
56-
EvalCacheJsonHandlers.writeMultiHit(input.fen, input.eval)
57-
sris.foreach: sri =>
58-
Bus.publish(_.sri(sri), hit)
59-
upgradeMon.count.increment(sris.size)
59+
newEval.so(_.sris.filter(_ != input.sri))
6060

6161
private def expire(sri: Sri): Unit =
6262
Option(members.remove(sri.value)).foreach:
@@ -71,14 +71,19 @@ final private class EvalCacheMulti(using
7171
else eval.copy(sris = newSris)
7272
)
7373

74-
scheduler.scheduleWithFixedDelay(1 minute, 1 minute): () =>
75-
upgradeMon.members.update(members.size)
76-
upgradeMon.evals.update(evals.size)
77-
upgradeMon.expirable.update(expirableSris.count)
78-
7974
private object EvalCacheMulti:
8075

8176
import EvalCacheUpgrade.*
8277

8378
case class WatchingMember(sri: Sri, variant: Variant, fens: List[Fen.Full]):
8479
def setups: List[Id] = fens.flatMap(Id.from(variant, _))
80+
81+
private val upgradeMon = Monitor.evalCache.multi.upgrade
82+
83+
def withMonitoring()(using ec: Executor, scheduler: Scheduler): EvalCacheMulti =
84+
val instance = EvalCacheMulti(expire => ExpireCallbackMemo[Sri](1 minute, expire))
85+
scheduler.scheduleWithFixedDelay(1 minute, 1 minute): () =>
86+
upgradeMon.members.update(instance.members.size)
87+
upgradeMon.evals.update(instance.evals.size)
88+
upgradeMon.expirable.update(instance.expirableSris.count)
89+
instance

src/main/scala/evalCache/EvalCacheUpgrade.scala

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package lila.ws
22
package evalCache
33

4+
import java.util.concurrent.ConcurrentHashMap
5+
import org.apache.pekko.actor.typed.Scheduler
46
import chess.format.UciPath
57
import play.api.libs.json.JsString
68
import scalalib.DebouncerFunction
79

8-
import java.util.concurrent.ConcurrentHashMap
9-
1010
import lila.ws.ipc.ClientIn.EvalHit
1111
import lila.ws.ipc.ClientOut.EvalGet
1212
import lila.ws.util.ExpireCallbackMemo
@@ -15,15 +15,12 @@ import lila.ws.util.ExpireCallbackMemo
1515
* by remembering the last evalGet of each socket member,
1616
* and listening to new evals stored.
1717
*/
18-
final private class EvalCacheUpgrade(using
19-
ec: Executor,
20-
scheduler: org.apache.pekko.actor.typed.Scheduler
21-
):
18+
final private class EvalCacheUpgrade(using ec: Executor, scheduler: Scheduler):
2219
import EvalCacheUpgrade.*
2320

2421
private val members = ConcurrentHashMap[SriString, WatchingMember](4096)
2522
private val evals = ConcurrentHashMap[SetupId, EvalState](1024)
26-
private val expirableSris = ExpireCallbackMemo[Sri](scheduler, 3 minutes, expire)
23+
private val expirableSris = ExpireCallbackMemo[Sri](3 minutes, expire)
2724

2825
private val debouncer = DebouncerFunction[SetupId](scheduler.scheduleOnce(5.seconds, _), 64)
2926

src/main/scala/util/ExpireCallbackMemo.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,17 @@ import org.apache.pekko.actor.typed.Scheduler
77
import java.util.concurrent.ConcurrentHashMap
88
import scala.jdk.CollectionConverters.*
99

10+
trait ExpireMemo[K]:
11+
def put(key: K): Unit
12+
def count: Int
13+
1014
// calls a function when a key expires
1115
final class ExpireCallbackMemo[K](
12-
scheduler: Scheduler,
1316
ttl: FiniteDuration,
1417
callback: K => Unit,
1518
initialCapacity: Int = 4096
16-
)(using Executor):
19+
)(using ec: Executor, scheduler: Scheduler)
20+
extends ExpireMemo[K]:
1721

1822
private val timeouts = ConcurrentHashMap[K, Cancellable](initialCapacity)
1923

0 commit comments

Comments
 (0)