From acd4ceb3f7aa21e00e2eca3cb1a40a7277ce8a19 Mon Sep 17 00:00:00 2001 From: Thanh Le Date: Tue, 26 Nov 2024 19:11:30 +0100 Subject: [PATCH 1/2] Fix order of function --- app/src/main/scala/http/ApiLogger.scala | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/src/main/scala/http/ApiLogger.scala b/app/src/main/scala/http/ApiLogger.scala index b9cbd50..e89e3fc 100644 --- a/app/src/main/scala/http/ApiLogger.scala +++ b/app/src/main/scala/http/ApiLogger.scala @@ -11,13 +11,6 @@ import org.typelevel.log4cats.Logger object ApiLogger: - private def isResponseError(res: Response[IO]): Boolean = - !res.status.isSuccess && res.status.code != 404 - - private def logError(req: Request[IO], res: Response[IO])(using Logger[IO]): IO[Unit] = - Http4sLogger.logMessage(req)(true, true)(Logger[IO].warn) >> - Http4sLogger.logMessage(res)(true, true)(Logger[IO].warn) - def apply(isVerbose: Boolean)(using Logger[IO]): HttpRoutes[IO] => HttpRoutes[IO] = if isVerbose then verboseLogger else errorLogger @@ -30,3 +23,11 @@ object ApiLogger: private def verboseLogger = RequestLogger.httpRoutes[IO](true, true) andThen ResponseLogger.httpRoutes[IO, Request[IO]](true, true) + + private def isResponseError(res: Response[IO]): Boolean = + !res.status.isSuccess && res.status.code != 404 + + private def logError(req: Request[IO], res: Response[IO])(using Logger[IO]): IO[Unit] = + Http4sLogger.logMessage(req)(true, true)(Logger[IO].warn) >> + Http4sLogger.logMessage(res)(true, true)(Logger[IO].warn) + From fb8df445da18f754cf30b1e78f1b199d9c1b9c12 Mon Sep 17 00:00:00 2001 From: Thanh Le Date: Tue, 26 Nov 2024 19:17:41 +0100 Subject: [PATCH 2/2] Remove StateRepository as it doesn't work --- app/src/main/scala/App.scala | 3 +- app/src/main/scala/AppConfig.scala | 11 +---- app/src/main/scala/Executor.scala | 9 ++-- app/src/main/scala/StateRepository.scala | 61 ------------------------ app/src/main/scala/http/ApiLogger.scala | 1 - app/src/test/scala/Helper.scala | 4 -- app/src/test/scala/IntegrationTest.scala | 3 +- app/src/test/scala/TaskCodecTest.scala | 17 ------- build.sbt | 4 -- project/Dependencies.scala | 5 -- 10 files changed, 7 insertions(+), 111 deletions(-) delete mode 100644 app/src/main/scala/StateRepository.scala delete mode 100644 app/src/test/scala/TaskCodecTest.scala diff --git a/app/src/main/scala/App.scala b/app/src/main/scala/App.scala index a12b5b2..448deac 100644 --- a/app/src/main/scala/App.scala +++ b/app/src/main/scala/App.scala @@ -33,5 +33,4 @@ class FishnetApp(res: AppResources, config: AppConfig)(using Logger[IO]): private def createExecutor: Resource[IO, Executor] = val lilaClient = LilaClient(res.redisPubsub) - val repository = StateRepository.instance(config.repository.path) - Monitor().toResource.flatMap(Executor.instance(lilaClient, repository, _, config.executor)) + Monitor().toResource.flatMap(Executor.instance(lilaClient, _, config.executor)) diff --git a/app/src/main/scala/AppConfig.scala b/app/src/main/scala/AppConfig.scala index 710a7da..437f76b 100644 --- a/app/src/main/scala/AppConfig.scala +++ b/app/src/main/scala/AppConfig.scala @@ -14,16 +14,14 @@ object AppConfig: RedisConfig.config, HttpServerConfig.config, KamonConfig.config, - ExecutorConfg.config, - RepositoryConfig.config + ExecutorConfg.config ).parMapN(AppConfig.apply) case class AppConfig( redis: RedisConfig, server: HttpServerConfig, kamon: KamonConfig, - executor: ExecutorConfig, - repository: RepositoryConfig + executor: ExecutorConfig ) case class HttpServerConfig(host: Host, port: Port, apiLogger: Boolean, shutdownTimeout: Int) @@ -52,8 +50,3 @@ case class ExecutorConfig(maxSize: Int) object ExecutorConfg: def maxSize = env("APP_MAX_MOVE_SIZE").or(prop("app.max.move.size")).as[Int].default(300) def config = maxSize.map(ExecutorConfig.apply) - -case class RepositoryConfig(path: Option[String]) -object RepositoryConfig: - def path = env("APP_BACKUP_FILE").or(prop("app.backup.file")).as[String].option - def config = path.map(RepositoryConfig.apply) diff --git a/app/src/main/scala/Executor.scala b/app/src/main/scala/Executor.scala index c50437a..085bbc5 100644 --- a/app/src/main/scala/Executor.scala +++ b/app/src/main/scala/Executor.scala @@ -31,16 +31,13 @@ object Executor: import AppState.* - def instance(client: LilaClient, repository: StateRepository, monitor: Monitor, config: ExecutorConfig)( - using Logger[IO] + def instance(client: LilaClient, monitor: Monitor, config: ExecutorConfig)(using + Logger[IO] ): Resource[IO, Executor] = Ref .of[IO, AppState](AppState.empty) .toResource - .flatMap: ref => - Resource - .make(repository.get.flatMap(ref.set))(_ => ref.get.flatMap(repository.save)) - .as(instance(ref, client, monitor, config)) + .map(instance(_, client, monitor, config)) def instance(ref: Ref[IO, AppState], client: LilaClient, monitor: Monitor, config: ExecutorConfig)(using Logger[IO] diff --git a/app/src/main/scala/StateRepository.scala b/app/src/main/scala/StateRepository.scala deleted file mode 100644 index ba6af46..0000000 --- a/app/src/main/scala/StateRepository.scala +++ /dev/null @@ -1,61 +0,0 @@ -package lila.fishnet - -import cats.effect.IO -import cats.syntax.all.* -import org.typelevel.log4cats.Logger - -trait StateRepository: - def get: IO[AppState] - def save(state: AppState): IO[Unit] - -object StateRepository: - - def instance(path: Option[String])(using Logger[IO]): StateRepository = - path.fold(noop)(file(_)) - - def noop(using Logger[IO]): StateRepository = - new: - def get: IO[AppState] = - Logger[IO].info("There is no configed path, return empty AppState") *> IO(AppState.empty) - def save(state: AppState): IO[Unit] = Logger[IO].info("There is no configed path, do nothing") - - def file(_path: String)(using Logger[IO]): StateRepository = - val path = fs2.io.file.Path(_path) - new: - def get: IO[AppState] = - Logger[IO].info(s"Reading state from $path") *> - fs2.io.file - .Files[IO] - .readAll(path) - .through(TasksSerDe.deserialize) - .compile - .toList - .map(AppState.fromTasks) - .handleErrorWith: e => - Logger[IO].error(e)(s"Failed to read state from $path") *> IO.pure(AppState.empty) - - def save(state: AppState): IO[Unit] = - Logger[IO].info(s"Saving ${state.size} tasks to $path") *> - fs2.Stream - .emits(state.tasks) - .through(TasksSerDe.serialize) - .through(fs2.text.utf8.encode) - .through(fs2.io.file.Files[IO].writeAll(path)) - .compile - .drain - .handleErrorWith: e => - Logger[IO].error(e)(s"Failed to write state to $path") - -object TasksSerDe: - - import fs2.data.json.* - import fs2.data.json.circe.* - - def deserialize: fs2.Pipe[IO, Byte, Work.Task] = - _.through(fs2.text.utf8.decode) - .through(tokens[IO, String]) - .through(codec.deserialize[IO, Work.Task]) - - def serialize: fs2.Pipe[IO, Work.Task, String] = - _.through(codec.serialize[IO, Work.Task]) - .through(render.compact) diff --git a/app/src/main/scala/http/ApiLogger.scala b/app/src/main/scala/http/ApiLogger.scala index e89e3fc..f7bc95b 100644 --- a/app/src/main/scala/http/ApiLogger.scala +++ b/app/src/main/scala/http/ApiLogger.scala @@ -30,4 +30,3 @@ object ApiLogger: private def logError(req: Request[IO], res: Response[IO])(using Logger[IO]): IO[Unit] = Http4sLogger.logMessage(req)(true, true)(Logger[IO].warn) >> Http4sLogger.logMessage(res)(true, true)(Logger[IO].warn) - diff --git a/app/src/test/scala/Helper.scala b/app/src/test/scala/Helper.scala index 12fbfd0..91f2486 100644 --- a/app/src/test/scala/Helper.scala +++ b/app/src/test/scala/Helper.scala @@ -10,7 +10,3 @@ object Helper: val noopLilaClient: LilaClient = new: def send(move: Lila.Response): IO[Unit] = IO.unit - - val noopStateRepository: StateRepository = new: - def get: IO[AppState] = IO.pure(AppState.empty) - def save(state: AppState): IO[Unit] = IO.unit diff --git a/app/src/test/scala/IntegrationTest.scala b/app/src/test/scala/IntegrationTest.scala index e1daa67..ab45cea 100644 --- a/app/src/test/scala/IntegrationTest.scala +++ b/app/src/test/scala/IntegrationTest.scala @@ -41,8 +41,7 @@ object IntegrationTest extends IOSuite: server = HttpServerConfig(ip"0.0.0.0", port"9999", apiLogger = false, shutdownTimeout = 30), redis = redis, kamon = KamonConfig(enabled = false), - executor = ExecutorConfig(maxSize = 300), - repository = RepositoryConfig(path = None) + executor = ExecutorConfig(maxSize = 300) ) test("health check should return healthy"): diff --git a/app/src/test/scala/TaskCodecTest.scala b/app/src/test/scala/TaskCodecTest.scala deleted file mode 100644 index 1ed4f7f..0000000 --- a/app/src/test/scala/TaskCodecTest.scala +++ /dev/null @@ -1,17 +0,0 @@ -package lila.fishnet - -import weaver.* - -object TaskCodecTest extends SimpleIOSuite: - - val json = - """{"id":"KPMMo99D","request":{"id":"xF0R6bn2","initialFen":"rnbqkbnr\/pppppppp\/8\/8\/8\/8\/PPPPPPPP\/RNBQKBNR w KQkq - 0 1","variant":"Standard","moves":"e2e4 e7e6 d2d4 d7d5 e4e5 c7c5 d4c5 b8c6 c1e3 d5d4 e3f4 f8c5 f1b5 g8e7","level":2,"clock":{"wtime":29880,"btime":31380,"inc":3}},"tries":0,"acquired":null,"createdAt":"2024-03-09T14:21:02.665278Z"}""" - - test("anti regression: serialize and deserialize a task"): - fs2.Stream - .emits(json.getBytes) - .through(TasksSerDe.deserialize) - .through(TasksSerDe.serialize) - .compile - .foldMonoid - .map(expect.same(_, json)) diff --git a/build.sbt b/build.sbt index 6614720..dfd454f 100644 --- a/build.sbt +++ b/build.sbt @@ -34,10 +34,6 @@ lazy val app = project circeCore, cirisCore, cirisHtt4s, - fs2, - fs2IO, - fs2Json, - fs2JsonCirce, http4sCirce, http4sDsl, http4sServer, diff --git a/project/Dependencies.scala b/project/Dependencies.scala index a69535b..127875f 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -21,11 +21,6 @@ object Dependencies { val catsCore = "org.typelevel" %% "cats-core" % "2.12.0" val catsEffect = "org.typelevel" %% "cats-effect" % V.catsEffect - val fs2 = "co.fs2" %% "fs2-core" % "3.11.0" - val fs2IO = "co.fs2" %% "fs2-io" % "3.11.0" - val fs2Json = "org.gnieh" %% "fs2-data-json" % "1.11.1" - val fs2JsonCirce = "org.gnieh" %% "fs2-data-json-circe" % "1.11.1" - val circeCore = circe("core") val circeLiteral = circe("literal") % Test