Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/ws-toilet' into ws-toilet
Browse files Browse the repository at this point in the history
  • Loading branch information
schlawg committed Sep 24, 2024
2 parents b1918f2 + bfb058a commit a175574
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/main/scala/LilaWs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ object LilaWs extends App:
given Executor = clientSystem.executionContext

lazy val mongo = wire[Mongo]
lazy val settings = wire[util.SettingStore]
lazy val groupedWithin = wire[util.GroupedWithin]
lazy val lightUserApi = wire[LightUserApi]
lazy val lilaRedis = wire[Lila]
Expand Down
1 change: 1 addition & 0 deletions src/main/scala/Mongo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ final class Mongo(config: Config)(using Executor) extends MongoHandlers:
def oauthColl = collNamed("oauth2_access_token")
def relayTourColl = collNamed("relay_tour")
def relayRoundColl = collNamed("relay")
def settingColl = collNamed("setting")
def studyColl = studyDb.map(_.collection("study"))(parasitic)
def evalCacheColl = yoloDb.map(_.collection("eval_cache2"))(parasitic)

Expand Down
41 changes: 41 additions & 0 deletions src/main/scala/util/SettingStore.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package lila.ws
package util

import org.apache.pekko.actor.typed.Scheduler
import reactivemongo.api.bson.*

/* A setting that is read from the database every `ttl`.
*
* Usage:
* val nbDogs: Setting[Int] = settingStore.makeSetting("dogs", 48, 1.minute)
* println("dogs: " + nbDogs.get)
*
* Note that the first reads are not guaranteed to be from the DB,
* but could return the hardcoded default value instead.
*
* To change the value of a setting, you need to update the DB directly, using mongosh:
* db.setting.updateOne({_id:'dogs'},{$set:{value:50}})
*/

case class Setting[A](default: A, ttl: FiniteDuration)(fetch: () => Future[Option[A]])(using
ec: Executor,
scheduler: Scheduler
):
private var value: A = default

def get: A = value

private def readFromDb(): Unit =
fetch().foreach: opt =>
value = opt | default

scheduler.scheduleWithFixedDelay(1.millis, ttl)(() => readFromDb())

final class SettingStore(mongo: Mongo)(using Executor, Scheduler):

def makeSetting[A: BSONReader](key: String, default: A, ttl: FiniteDuration = 10.seconds): Setting[A] =
Setting[A](default, ttl): () =>
mongo.settingColl.flatMap:
_.find(selector = BSONDocument("_id" -> key))
.one[BSONDocument]
.map(_.flatMap(_.getAsOpt[A]("value")))

0 comments on commit a175574

Please sign in to comment.