From a92b188507e95b2506d80bdf0ab75877ea05ea33 Mon Sep 17 00:00:00 2001
From: Alpha Ho <666504+alphaho@users.noreply.github.com>
Date: Sat, 12 Apr 2025 20:25:55 +0900
Subject: [PATCH 1/7] Add tapir framework and its variants
---
frameworks/Scala/tapir/README.md | 27 ++++
frameworks/Scala/tapir/benchmark_config.json | 121 ++++++++++++++++++
frameworks/Scala/tapir/build.sbt | 89 +++++++++++++
.../tapir/common/src/main/scala/Payload.scala | 1 +
frameworks/Scala/tapir/config.toml | 80 ++++++++++++
.../scala/TapirHttp4sServerZioBenchmark.scala | 55 ++++++++
.../scala/TapirHttp4sServerBenchmark.scala | 50 ++++++++
.../scala/TapirNettyCatsServerBenchmark.scala | 54 ++++++++
.../scala/TapirNettyZioServerBenchmark.scala | 57 +++++++++
.../src/main/scala/Main.scala | 42 ++++++
.../Scala/tapir/project/build.properties | 1 +
frameworks/Scala/tapir/project/plugins.sbt | 1 +
.../Scala/tapir/tapir-http4s-zio.dockerfile | 11 ++
.../Scala/tapir/tapir-http4s.dockerfile | 11 ++
.../Scala/tapir/tapir-netty-cats.dockerfile | 11 ++
.../Scala/tapir/tapir-netty-zio.dockerfile | 11 ++
.../Scala/tapir/tapir-pekko-http.dockerfile | 11 ++
frameworks/Scala/tapir/tapir.dockerfile | 11 ++
.../scala/TapirZioHttpServerBenchmark.scala | 56 ++++++++
19 files changed, 700 insertions(+)
create mode 100644 frameworks/Scala/tapir/README.md
create mode 100644 frameworks/Scala/tapir/benchmark_config.json
create mode 100644 frameworks/Scala/tapir/build.sbt
create mode 100644 frameworks/Scala/tapir/common/src/main/scala/Payload.scala
create mode 100644 frameworks/Scala/tapir/config.toml
create mode 100644 frameworks/Scala/tapir/http4s-server-zio/src/main/scala/TapirHttp4sServerZioBenchmark.scala
create mode 100644 frameworks/Scala/tapir/http4s-server/src/main/scala/TapirHttp4sServerBenchmark.scala
create mode 100644 frameworks/Scala/tapir/netty-cats-server/src/main/scala/TapirNettyCatsServerBenchmark.scala
create mode 100644 frameworks/Scala/tapir/netty-zio-server/src/main/scala/TapirNettyZioServerBenchmark.scala
create mode 100644 frameworks/Scala/tapir/pekko-http-server/src/main/scala/Main.scala
create mode 100644 frameworks/Scala/tapir/project/build.properties
create mode 100644 frameworks/Scala/tapir/project/plugins.sbt
create mode 100644 frameworks/Scala/tapir/tapir-http4s-zio.dockerfile
create mode 100644 frameworks/Scala/tapir/tapir-http4s.dockerfile
create mode 100644 frameworks/Scala/tapir/tapir-netty-cats.dockerfile
create mode 100644 frameworks/Scala/tapir/tapir-netty-zio.dockerfile
create mode 100644 frameworks/Scala/tapir/tapir-pekko-http.dockerfile
create mode 100644 frameworks/Scala/tapir/tapir.dockerfile
create mode 100644 frameworks/Scala/tapir/zio-http-server/src/main/scala/TapirZioHttpServerBenchmark.scala
diff --git a/frameworks/Scala/tapir/README.md b/frameworks/Scala/tapir/README.md
new file mode 100644
index 00000000000..7edfe1a0342
--- /dev/null
+++ b/frameworks/Scala/tapir/README.md
@@ -0,0 +1,27 @@
+# Tapir Benchmarking Test
+
+This is a simple test to benchmark the performance of the Tapir libraries along with different backends in Scala.
+
+### Test Type Implementation Source Code
+
+* JSON
+* PLAINTEXT
+
+## Software Versions
+
+* [Java OpenJDK 21](https://adoptium.net/temurin/releases/)
+* [Scala 3.6.4](https://www.scala-lang.org/)
+* [Tapir 1.11.24](https://tapir.softwaremill.com)
+
+### Backend Implementations
+* [Tapir running as zio-http server](https://tapir.softwaremill.com/en/latest/server/ziohttp.html)
+* [Tapir running as http4s server](https://tapir.softwaremill.com/en/latest/server/http4s.html)
+* [as an http4s server using ZIO](https://tapir.softwaremill.com/en/latest/server/zio-http4s.html)
+* [Tapir running as Netty-based server(Cats)](https://tapir.softwaremill.com/en/latest/server/netty.html)
+* [Tapir running as Netty-based server(ZIO)](https://tapir.softwaremill.com/en/latest/server/netty.html)
+* [Tapir running as pekko-http server](https://tapir.softwaremill.com/en/latest/server/pekkohttp.html)
+
+## Test URLs
+
+* JSON - http://localhost:8080/json
+* PLAINTEXT - http://localhost:8080/plaintext
diff --git a/frameworks/Scala/tapir/benchmark_config.json b/frameworks/Scala/tapir/benchmark_config.json
new file mode 100644
index 00000000000..442ad8d0094
--- /dev/null
+++ b/frameworks/Scala/tapir/benchmark_config.json
@@ -0,0 +1,121 @@
+{
+ "framework": "tapir",
+ "tests": [
+ {
+ "default": {
+ "plaintext_url": "/plaintext",
+ "json_url": "/json",
+ "port": 8080,
+ "database": "None",
+ "approach": "Realistic",
+ "classification": "Micro",
+ "framework": "tapir",
+ "language": "Scala",
+ "flavor": "None",
+ "orm": "Raw",
+ "platform": "Netty",
+ "webserver": "None",
+ "database_os": "Linux",
+ "os": "Linux",
+ "display_name": "tapir as zio-http server",
+ "notes": "https://tapir.softwaremill.com/en/latest/server/ziohttp.html",
+ "versus": "None"
+ },
+ "http4s": {
+ "plaintext_url": "/plaintext",
+ "json_url": "/json",
+ "port": 8080,
+ "database": "None",
+ "approach": "Realistic",
+ "classification": "Micro",
+ "framework": "tapir",
+ "language": "Scala",
+ "flavor": "None",
+ "orm": "Raw",
+ "platform": "Netty",
+ "webserver": "None",
+ "database_os": "Linux",
+ "os": "Linux",
+ "display_name": "tapir as http4s server",
+ "notes": "https://tapir.softwaremill.com/en/latest/server/http4s.html",
+ "versus": "None"
+ },
+ "http4s-zio": {
+ "plaintext_url": "/plaintext",
+ "json_url": "/json",
+ "port": 8080,
+ "database": "None",
+ "approach": "Realistic",
+ "classification": "Micro",
+ "framework": "tapir",
+ "language": "Scala",
+ "flavor": "None",
+ "orm": "Raw",
+ "platform": "Netty",
+ "webserver": "None",
+ "database_os": "Linux",
+ "os": "Linux",
+ "display_name": "tapir as http4s server using ZIO",
+ "notes": "https://tapir.softwaremill.com/en/latest/server/zio-http4s.html",
+ "versus": "None"
+ },
+ "netty-cats": {
+ "plaintext_url": "/plaintext",
+ "json_url": "/json",
+ "port": 8080,
+ "database": "None",
+ "approach": "Realistic",
+ "classification": "Micro",
+ "framework": "tapir",
+ "language": "Scala",
+ "flavor": "None",
+ "orm": "Raw",
+ "platform": "Netty",
+ "webserver": "None",
+ "database_os": "Linux",
+ "os": "Linux",
+ "display_name": "tapir as netty(cats) server",
+ "notes": "https://tapir.softwaremill.com/en/latest/server/netty.html",
+ "versus": "None"
+ },
+ "netty-zio": {
+ "plaintext_url": "/plaintext",
+ "json_url": "/json",
+ "port": 8080,
+ "database": "None",
+ "approach": "Realistic",
+ "classification": "Micro",
+ "framework": "tapir",
+ "language": "Scala",
+ "flavor": "None",
+ "orm": "Raw",
+ "platform": "Netty",
+ "webserver": "None",
+ "database_os": "Linux",
+ "os": "Linux",
+ "display_name": "tapir as netty(zio) server",
+ "notes": "https://tapir.softwaremill.com/en/latest/server/netty.html",
+ "versus": "None"
+ },
+ "pekko-http": {
+ "plaintext_url": "/plaintext",
+ "json_url": "/json",
+ "port": 8080,
+ "database": "None",
+ "approach": "Realistic",
+ "classification": "Micro",
+ "framework": "tapir",
+ "language": "Scala",
+ "flavor": "None",
+ "orm": "Raw",
+ "platform": "Netty",
+ "webserver": "None",
+ "database_os": "Linux",
+ "os": "Linux",
+ "display_name": "tapir as pekko-http server",
+ "notes": "https://tapir.softwaremill.com/en/latest/server/pekkohttp.html",
+ "versus": "None"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frameworks/Scala/tapir/build.sbt b/frameworks/Scala/tapir/build.sbt
new file mode 100644
index 00000000000..b787ee18a29
--- /dev/null
+++ b/frameworks/Scala/tapir/build.sbt
@@ -0,0 +1,89 @@
+name := "tapir-benchmark"
+
+ThisBuild / version := "1.0.0"
+ThisBuild / scalaVersion := "3.6.4"
+
+val tapirVersion = "1.11.24"
+
+val commonAssemblySettings = assembly / assemblyMergeStrategy := {
+ case x if x.contains("io.netty.versions.properties") => MergeStrategy.discard
+ case x if x.contains("module-info.class") => MergeStrategy.discard
+ case x =>
+ val oldStrategy = (assembly / assemblyMergeStrategy).value
+ oldStrategy(x)
+}
+
+lazy val common = (project in file("common"))
+ .settings(
+ name := "tapir-benchmark-common"
+ )
+
+lazy val `zio-http-server` = (project in file("zio-http-server"))
+ .dependsOn(common)
+ .settings(
+ name := "tapir-zio-http-server",
+ libraryDependencies ++= Seq(
+ "com.softwaremill.sttp.tapir" %% "tapir-zio-http-server" % tapirVersion,
+ "com.softwaremill.sttp.tapir" %% "tapir-json-zio" % tapirVersion
+ ),
+ commonAssemblySettings
+ )
+
+lazy val `http4s-server` = (project in file("http4s-server"))
+ .dependsOn(common)
+ .settings(
+ name := "tapir-http4s-server",
+ libraryDependencies ++= Seq(
+ "com.softwaremill.sttp.tapir" %% "tapir-http4s-server" % tapirVersion,
+ "com.softwaremill.sttp.tapir" %% "tapir-json-circe" % tapirVersion,
+ "org.http4s" %% "http4s-blaze-server" % "0.23.17",
+ ),
+ commonAssemblySettings
+ )
+
+lazy val `http4s-server-zio` = (project in file("http4s-server-zio"))
+ .dependsOn(common)
+ .settings(
+ name := "tapir-http4s-server-zio",
+ libraryDependencies ++= Seq(
+ "com.softwaremill.sttp.tapir" %% "tapir-http4s-server-zio" % tapirVersion,
+ "com.softwaremill.sttp.tapir" %% "tapir-json-circe" % tapirVersion,
+ "org.http4s" %% "http4s-blaze-server" % "0.23.17",
+ "dev.zio" %% "zio-interop-cats" % "23.1.0.5"
+ ),
+ commonAssemblySettings
+ )
+
+lazy val `netty-zio-server` = (project in file("netty-zio-server"))
+ .dependsOn(common)
+ .settings(
+ name := "tapir-netty-zio-server",
+ libraryDependencies ++= Seq(
+ "com.softwaremill.sttp.tapir" %% "tapir-netty-server-zio" % tapirVersion,
+ "com.softwaremill.sttp.tapir" %% "tapir-json-zio" % tapirVersion,
+ ),
+ commonAssemblySettings
+ )
+
+lazy val `netty-cats-server` = (project in file("netty-cats-server"))
+ .dependsOn(common)
+ .settings(
+ name := "tapir-netty-cats-server",
+ libraryDependencies ++= Seq(
+ "com.softwaremill.sttp.tapir" %% "tapir-netty-server-cats" % tapirVersion,
+ "com.softwaremill.sttp.tapir" %% "tapir-json-circe" % tapirVersion,
+ "org.http4s" %% "http4s-blaze-server" % "0.23.17",
+ ),
+ commonAssemblySettings
+ )
+
+lazy val `pekko-http-server` = (project in file("pekko-http-server"))
+ .dependsOn(common)
+ .settings(
+ name := "tapir-pekko-http-server",
+ libraryDependencies ++= Seq(
+ "com.softwaremill.sttp.tapir" %% "tapir-pekko-http-server" % tapirVersion,
+ "com.softwaremill.sttp.tapir" %% "tapir-json-circe" % tapirVersion,
+ ),
+ commonAssemblySettings
+ )
diff --git a/frameworks/Scala/tapir/common/src/main/scala/Payload.scala b/frameworks/Scala/tapir/common/src/main/scala/Payload.scala
new file mode 100644
index 00000000000..2b886ef91b8
--- /dev/null
+++ b/frameworks/Scala/tapir/common/src/main/scala/Payload.scala
@@ -0,0 +1 @@
+case class Payload(message: String)
diff --git a/frameworks/Scala/tapir/config.toml b/frameworks/Scala/tapir/config.toml
new file mode 100644
index 00000000000..9d5f42eba87
--- /dev/null
+++ b/frameworks/Scala/tapir/config.toml
@@ -0,0 +1,80 @@
+[framework]
+name = "tapir"
+
+[main]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+approach = "Realistic"
+classification = "Micro"
+database = "None"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "Netty"
+webserver = "None"
+versus = "None"
+
+[http4s]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+approach = "Realistic"
+classification = "Micro"
+database = "None"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "Netty"
+webserver = "None"
+versus = "None"
+
+[http4s-zio]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+approach = "Realistic"
+classification = "Micro"
+database = "None"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "Netty"
+webserver = "None"
+versus = "None"
+
+[netty-cats]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+approach = "Realistic"
+classification = "Micro"
+database = "None"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "Netty"
+webserver = "None"
+versus = "None"
+
+[netty-zio]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+approach = "Realistic"
+classification = "Micro"
+database = "None"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "Netty"
+webserver = "None"
+versus = "None"
+
+[pekko-http]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+approach = "Realistic"
+classification = "Micro"
+database = "None"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "Netty"
+webserver = "None"
+versus = "None"
\ No newline at end of file
diff --git a/frameworks/Scala/tapir/http4s-server-zio/src/main/scala/TapirHttp4sServerZioBenchmark.scala b/frameworks/Scala/tapir/http4s-server-zio/src/main/scala/TapirHttp4sServerZioBenchmark.scala
new file mode 100644
index 00000000000..8e93bd7445c
--- /dev/null
+++ b/frameworks/Scala/tapir/http4s-server-zio/src/main/scala/TapirHttp4sServerZioBenchmark.scala
@@ -0,0 +1,55 @@
+import io.circe.generic.auto.*
+import org.http4s.HttpRoutes
+import org.http4s.blaze.server.BlazeServerBuilder
+import org.http4s.server.Router
+import sttp.model.{Header, HeaderNames, StatusCode}
+import sttp.tapir.generic.auto.*
+import sttp.tapir.json.circe.*
+import sttp.tapir.server.http4s.ztapir.ZHttp4sServerInterpreter
+import sttp.tapir.ztapir.*
+import zio.*
+
+import java.time.format.DateTimeFormatter
+import java.time.{Clock, LocalDateTime, ZoneOffset, ZonedDateTime}
+import java.util.Date
+import java.util.concurrent.locks.LockSupport
+import scala.concurrent.ExecutionContext
+import zio.interop.catz.*
+
+object TapirHttp4sServerZioBenchmark extends ZIOAppDefault:
+ private val STATIC_SERVER_NAME = "tapir-http4s-server-zio"
+
+ private val plainTextMessage: String = "Hello, World!"
+
+ private val plaintextEndpoint: ZServerEndpoint[Any, Any] =
+ endpoint.get.in("plaintext")
+ .out(header(HeaderNames.Server, STATIC_SERVER_NAME))
+ .out(stringBody)
+ .zServerLogic(_ => ZIO.succeed(plainTextMessage))
+
+ private val jsonEndpoint: ZServerEndpoint[Any, Any] =
+ endpoint.get.in("json")
+ .out(header(HeaderNames.Server, STATIC_SERVER_NAME))
+ .out(jsonBody[Payload])
+ .zServerLogic(_ => ZIO.succeed(Payload(plainTextMessage)))
+
+
+ private val declaredPort = 8080
+ private val declaredHost = "0.0.0.0"
+
+ private val routes: HttpRoutes[Task] = ZHttp4sServerInterpreter()
+ .from(List(plaintextEndpoint, jsonEndpoint))
+ .toRoutes
+
+ implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global
+
+ override def run: URIO[Any, ExitCode] =
+ ZIO.executor.flatMap(executor =>
+ BlazeServerBuilder[Task]
+ .withExecutionContext(executor.asExecutionContext)
+ .bindHttp(8080, declaredHost)
+ .withHttpApp(Router("/" -> routes).orNotFound)
+ .serve
+ .compile
+ .drain
+ ).exitCode
diff --git a/frameworks/Scala/tapir/http4s-server/src/main/scala/TapirHttp4sServerBenchmark.scala b/frameworks/Scala/tapir/http4s-server/src/main/scala/TapirHttp4sServerBenchmark.scala
new file mode 100644
index 00000000000..f8dadd8d446
--- /dev/null
+++ b/frameworks/Scala/tapir/http4s-server/src/main/scala/TapirHttp4sServerBenchmark.scala
@@ -0,0 +1,50 @@
+import cats.effect.{ExitCode, IO, IOApp}
+import io.circe.generic.auto.*
+import org.http4s.HttpRoutes
+import org.http4s.blaze.server.BlazeServerBuilder
+import org.http4s.server.Router
+import sttp.model.{Header, HeaderNames, StatusCode}
+import sttp.tapir.*
+import sttp.tapir.generic.auto.*
+import sttp.tapir.json.circe.*
+import sttp.tapir.server.http4s.Http4sServerInterpreter
+
+import java.time.format.DateTimeFormatter
+import java.time.{Clock, LocalDateTime, ZoneOffset, ZonedDateTime}
+import java.util.Date
+import java.util.concurrent.locks.LockSupport
+import scala.concurrent.ExecutionContext
+
+object TapirHttp4sServerBenchmark extends IOApp:
+ private val STATIC_SERVER_NAME = "tapir-http4s-server"
+
+ private val plainTextMessage: String = "Hello, World!"
+
+ val plaintextEndpoint =
+ endpoint.get.in("plaintext")
+ .out(header(HeaderNames.Server, STATIC_SERVER_NAME))
+ .out(stringBody)
+ .serverLogic(_ => IO.pure[Either[Unit, String]](Right(plainTextMessage)))
+
+ val jsonEndpoint =
+ endpoint.get.in("json")
+ .out(header(HeaderNames.Server, STATIC_SERVER_NAME))
+ .out(jsonBody[Payload])
+ .serverLogic(_ => IO.pure[Either[Unit, Payload]](Right(Payload(plainTextMessage))))
+
+
+ private val declaredPort = 8080
+ private val declaredHost = "0.0.0.0"
+
+ val routes = Http4sServerInterpreter[IO]().toRoutes(List(plaintextEndpoint, jsonEndpoint))
+
+ implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global
+
+ override def run(args: List[String]): IO[ExitCode] =
+ BlazeServerBuilder[IO]
+ .withExecutionContext(ec)
+ .bindHttp(declaredPort, declaredHost)
+ .withHttpApp(Router("/" -> routes).orNotFound)
+ .resource
+ .useForever
+ .as(ExitCode.Success)
diff --git a/frameworks/Scala/tapir/netty-cats-server/src/main/scala/TapirNettyCatsServerBenchmark.scala b/frameworks/Scala/tapir/netty-cats-server/src/main/scala/TapirNettyCatsServerBenchmark.scala
new file mode 100644
index 00000000000..824b538a079
--- /dev/null
+++ b/frameworks/Scala/tapir/netty-cats-server/src/main/scala/TapirNettyCatsServerBenchmark.scala
@@ -0,0 +1,54 @@
+import cats.effect.{IO, IOApp}
+import io.circe.generic.auto.*
+import sttp.model.{Header, HeaderNames}
+import sttp.tapir.*
+import sttp.tapir.generic.auto.*
+import sttp.tapir.json.circe.*
+import sttp.tapir.server.netty.cats.NettyCatsServer
+
+import java.time.Instant
+
+object TapirNettyCatsServerBenchmark extends IOApp.Simple:
+ private val STATIC_SERVER_NAME = "tapir-netty-cats-server"
+
+ private val plainTextMessage: String = "Hello, World!"
+
+ val plaintextEndpoint =
+ endpoint.get.in("plaintext")
+ .out(header(HeaderNames.Server, STATIC_SERVER_NAME))
+ .out(header[String](HeaderNames.Date))
+ .out(stringBody)
+ .serverLogic(_ =>
+ for {
+ now <- IO.realTime.map(time => Instant.ofEpochMilli(time.toMillis))
+ } yield Right(Header.toHttpDateString(now) -> plainTextMessage)
+ )
+
+ val jsonEndpoint =
+ endpoint.get.in("json")
+ .out(header(HeaderNames.Server, STATIC_SERVER_NAME))
+ .out(header[String](HeaderNames.Date))
+ .out(jsonBody[Payload])
+ .serverLogic(_ =>
+ for {
+ now <- IO.realTime.map(time => Instant.ofEpochMilli(time.toMillis))
+ } yield Right(Header.toHttpDateString(now) -> Payload(plainTextMessage))
+ )
+
+
+ private val declaredPort = 8080
+ private val declaredHost = "0.0.0.0"
+
+ override def run = NettyCatsServer
+ .io()
+ .use { server =>
+ for {
+ _ <- server
+ .port(declaredPort)
+ .host(declaredHost)
+ .addEndpoint(plaintextEndpoint)
+ .addEndpoint(jsonEndpoint)
+ .start()
+ _ <- IO.never
+ } yield ()
+ }
diff --git a/frameworks/Scala/tapir/netty-zio-server/src/main/scala/TapirNettyZioServerBenchmark.scala b/frameworks/Scala/tapir/netty-zio-server/src/main/scala/TapirNettyZioServerBenchmark.scala
new file mode 100644
index 00000000000..fbd2fa34477
--- /dev/null
+++ b/frameworks/Scala/tapir/netty-zio-server/src/main/scala/TapirNettyZioServerBenchmark.scala
@@ -0,0 +1,57 @@
+import sttp.model.{Header, HeaderNames}
+import sttp.tapir.Schema
+import sttp.tapir.json.zio.*
+import sttp.tapir.server.netty.zio.NettyZioServer
+import sttp.tapir.ztapir.*
+import zio.*
+import zio.json.*
+import sttp.tapir.server.netty.*
+
+object TapirNettyZioServerBenchmark extends ZIOAppDefault {
+ private val STATIC_SERVER_NAME = "tapir-netty-zio-server"
+
+ private val plainTextMessage: String = "Hello, World!"
+
+ given JsonCodec[Payload] = DeriveJsonCodec.gen
+ given Schema[Payload] = Schema.derived
+
+ override def run = {
+ val plaintextRoute: ZServerEndpoint[Any, Any] =
+ endpoint.get.in("plaintext")
+ .out(header(HeaderNames.Server, STATIC_SERVER_NAME))
+ .out(header[String](HeaderNames.Date))
+ .out(stringBody)
+ .zServerLogic { _ =>
+ for {
+ now <- Clock.currentDateTime
+ } yield Header.toHttpDateString(now.toInstant) -> plainTextMessage
+ }
+
+ val jsonRoute: ZServerEndpoint[Any, Any] =
+ endpoint.get.in("json")
+ .out(header(HeaderNames.Server, STATIC_SERVER_NAME))
+ .out(header[String](HeaderNames.Date))
+ .out(jsonBody[Payload])
+ .zServerLogic { _ =>
+ for {
+ now <- Clock.currentDateTime
+ } yield Header.toHttpDateString(now.toInstant) -> Payload(plainTextMessage)
+ }
+
+ val config = NettyConfig.default
+ .withSocketKeepAlive
+ .copy(lingerTimeout = None)
+
+
+
+ val server = NettyZioServer[Any](config)
+ .addEndpoint(plaintextRoute)
+ .addEndpoint(jsonRoute)
+ .host("0.0.0.0")
+ .port(8080)
+
+ server.start().flatMap { _ =>
+ ZIO.never
+ }
+ }
+}
\ No newline at end of file
diff --git a/frameworks/Scala/tapir/pekko-http-server/src/main/scala/Main.scala b/frameworks/Scala/tapir/pekko-http-server/src/main/scala/Main.scala
new file mode 100644
index 00000000000..ebcdd901368
--- /dev/null
+++ b/frameworks/Scala/tapir/pekko-http-server/src/main/scala/Main.scala
@@ -0,0 +1,42 @@
+import io.circe.generic.auto.*
+import org.apache.pekko.actor.ActorSystem
+import org.apache.pekko.http.scaladsl.Http
+import sttp.model.HeaderNames
+import sttp.tapir.*
+import sttp.tapir.json.circe.*
+import sttp.tapir.server.pekkohttp.PekkoHttpServerInterpreter
+
+import scala.concurrent.Future
+
+@main def tapirPekkoServerBenchmark(): Unit = {
+ implicit val actorSystem: ActorSystem = ActorSystem()
+ import actorSystem.dispatcher
+
+ val STATIC_SERVER_NAME = "tapir-pekko-http-server"
+
+ val plainTextMessage: String = "Hello, World!"
+
+ given Schema[Payload] = Schema.derived
+
+ val plaintextRoute =
+ endpoint.get
+ .in("plaintext")
+ .out(header(HeaderNames.Server, STATIC_SERVER_NAME))
+ .out(stringBody)
+ .serverLogic[Future] { _ =>
+ Future.successful(Right(plainTextMessage))
+ }
+
+ val jsonRoute =
+ endpoint.get
+ .in("json")
+ .out(header(HeaderNames.Server, STATIC_SERVER_NAME))
+ .out(jsonBody[Payload])
+ .serverLogic[Future] { _ =>
+ Future.successful(Right(Payload(plainTextMessage)))
+ }
+
+ val route = PekkoHttpServerInterpreter().toRoute(List(plaintextRoute, jsonRoute))
+
+ Http().newServerAt("0.0.0.0", 8080).bindFlow(route)
+}
\ No newline at end of file
diff --git a/frameworks/Scala/tapir/project/build.properties b/frameworks/Scala/tapir/project/build.properties
new file mode 100644
index 00000000000..0882e8a3906
--- /dev/null
+++ b/frameworks/Scala/tapir/project/build.properties
@@ -0,0 +1 @@
+sbt.version = 1.10.7
\ No newline at end of file
diff --git a/frameworks/Scala/tapir/project/plugins.sbt b/frameworks/Scala/tapir/project/plugins.sbt
new file mode 100644
index 00000000000..f8ea5d0fbb0
--- /dev/null
+++ b/frameworks/Scala/tapir/project/plugins.sbt
@@ -0,0 +1 @@
+addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.3.1")
diff --git a/frameworks/Scala/tapir/tapir-http4s-zio.dockerfile b/frameworks/Scala/tapir/tapir-http4s-zio.dockerfile
new file mode 100644
index 00000000000..7ef30135459
--- /dev/null
+++ b/frameworks/Scala/tapir/tapir-http4s-zio.dockerfile
@@ -0,0 +1,11 @@
+FROM sbtscala/scala-sbt:eclipse-temurin-21.0.6_7_1.10.11_3.6.4
+
+WORKDIR /tapir-benchmark
+COPY http4s-server-zio http4s-server-zio
+COPY common common
+COPY project project
+COPY build.sbt build.sbt
+RUN sbt http4s-server-zio/assembly
+
+EXPOSE 8080
+CMD ["java", "-Xms2G", "-Xmx2G", "-server", "-jar", "/tapir-benchmark/http4s-server-zio/target/scala-3.6.4/tapir-http4s-server-zio-assembly-1.0.0.jar"]
\ No newline at end of file
diff --git a/frameworks/Scala/tapir/tapir-http4s.dockerfile b/frameworks/Scala/tapir/tapir-http4s.dockerfile
new file mode 100644
index 00000000000..892210bc692
--- /dev/null
+++ b/frameworks/Scala/tapir/tapir-http4s.dockerfile
@@ -0,0 +1,11 @@
+FROM sbtscala/scala-sbt:eclipse-temurin-21.0.6_7_1.10.11_3.6.4
+
+WORKDIR /tapir-benchmark
+COPY http4s-server http4s-server
+COPY common common
+COPY project project
+COPY build.sbt build.sbt
+RUN sbt http4s-server/assembly
+
+EXPOSE 8080
+CMD ["java", "-Xms2G", "-Xmx2G", "-server", "-jar", "/tapir-benchmark/http4s-server/target/scala-3.6.4/tapir-http4s-server-assembly-1.0.0.jar"]
\ No newline at end of file
diff --git a/frameworks/Scala/tapir/tapir-netty-cats.dockerfile b/frameworks/Scala/tapir/tapir-netty-cats.dockerfile
new file mode 100644
index 00000000000..5dec450e3d5
--- /dev/null
+++ b/frameworks/Scala/tapir/tapir-netty-cats.dockerfile
@@ -0,0 +1,11 @@
+FROM sbtscala/scala-sbt:eclipse-temurin-21.0.6_7_1.10.11_3.6.4
+
+WORKDIR /tapir-benchmark
+COPY netty-cats-server netty-cats-server
+COPY common common
+COPY project project
+COPY build.sbt build.sbt
+RUN sbt netty-cats-server/assembly
+
+EXPOSE 8080
+CMD ["java", "-Xms2G", "-Xmx2G", "-server", "-Dio.netty.leakDetection.level=disabled", "-Dio.netty.recycler.maxCapacityPerThread=0", "-jar", "/tapir-benchmark/netty-cats-server/target/scala-3.6.4/tapir-netty-cats-server-assembly-1.0.0.jar"]
\ No newline at end of file
diff --git a/frameworks/Scala/tapir/tapir-netty-zio.dockerfile b/frameworks/Scala/tapir/tapir-netty-zio.dockerfile
new file mode 100644
index 00000000000..aa9c3607080
--- /dev/null
+++ b/frameworks/Scala/tapir/tapir-netty-zio.dockerfile
@@ -0,0 +1,11 @@
+FROM sbtscala/scala-sbt:eclipse-temurin-21.0.6_7_1.10.11_3.6.4
+
+WORKDIR /tapir-benchmark
+COPY netty-zio-server netty-zio-server
+COPY common common
+COPY project project
+COPY build.sbt build.sbt
+RUN sbt netty-zio-server/assembly
+
+EXPOSE 8080
+CMD ["java", "-Xms2G", "-Xmx2G", "-server", "-Dio.netty.leakDetection.level=disabled", "-Dio.netty.recycler.maxCapacityPerThread=0", "-jar", "/tapir-benchmark/netty-zio-server/target/scala-3.6.4/tapir-netty-zio-server-assembly-1.0.0.jar"]
\ No newline at end of file
diff --git a/frameworks/Scala/tapir/tapir-pekko-http.dockerfile b/frameworks/Scala/tapir/tapir-pekko-http.dockerfile
new file mode 100644
index 00000000000..f21480ae5be
--- /dev/null
+++ b/frameworks/Scala/tapir/tapir-pekko-http.dockerfile
@@ -0,0 +1,11 @@
+FROM sbtscala/scala-sbt:eclipse-temurin-21.0.6_7_1.10.11_3.6.4
+
+WORKDIR /tapir-benchmark
+COPY pekko-http-server pekko-http-server
+COPY common common
+COPY project project
+COPY build.sbt build.sbt
+RUN sbt pekko-http-server/assembly
+
+EXPOSE 8080
+CMD ["java", "-Xms2G", "-Xmx2G", "-server", "-jar", "/tapir-benchmark/pekko-http-server/target/scala-3.6.4/tapir-pekko-http-server-assembly-1.0.0.jar"]
\ No newline at end of file
diff --git a/frameworks/Scala/tapir/tapir.dockerfile b/frameworks/Scala/tapir/tapir.dockerfile
new file mode 100644
index 00000000000..33e2438eea7
--- /dev/null
+++ b/frameworks/Scala/tapir/tapir.dockerfile
@@ -0,0 +1,11 @@
+FROM sbtscala/scala-sbt:eclipse-temurin-21.0.6_7_1.10.11_3.6.4
+
+WORKDIR /tapir-benchmark
+COPY zio-http-server zio-http-server
+COPY common common
+COPY project project
+COPY build.sbt build.sbt
+RUN sbt zio-http-server/assembly
+
+EXPOSE 8080
+CMD ["java", "-Xms2G", "-Xmx2G", "-server", "-Dio.netty.leakDetection.level=disabled", "-Dio.netty.recycler.maxCapacityPerThread=0", "-jar", "/tapir-benchmark/zio-http-server/target/scala-3.6.4/tapir-zio-http-server-assembly-1.0.0.jar"]
\ No newline at end of file
diff --git a/frameworks/Scala/tapir/zio-http-server/src/main/scala/TapirZioHttpServerBenchmark.scala b/frameworks/Scala/tapir/zio-http-server/src/main/scala/TapirZioHttpServerBenchmark.scala
new file mode 100644
index 00000000000..59e189b01bd
--- /dev/null
+++ b/frameworks/Scala/tapir/zio-http-server/src/main/scala/TapirZioHttpServerBenchmark.scala
@@ -0,0 +1,56 @@
+import sttp.model.{Header, HeaderNames}
+import sttp.tapir.Schema
+import sttp.tapir.json.zio.*
+import sttp.tapir.server.ziohttp.ZioHttpInterpreter
+import sttp.tapir.ztapir.*
+import zio.*
+import zio.http.netty.NettyConfig
+import zio.http.netty.NettyConfig.LeakDetectionLevel
+import zio.http.{Request, Response, Routes, Server}
+import zio.json.*
+
+import java.lang.Runtime as JRuntime
+
+object TapirZioHttpServerBenchmark extends ZIOAppDefault {
+ private val STATIC_SERVER_NAME = "zio-http-tapir"
+
+ private val plainTextMessage: String = "Hello, World!"
+ private val NUM_PROCESSORS = JRuntime.getRuntime.availableProcessors()
+
+ given JsonCodec[Payload] = DeriveJsonCodec.gen
+ given Schema[Payload] = Schema.derived
+
+ override def run = {
+ val plaintextRoute: ZServerEndpoint[Any, Any] =
+ endpoint.get.in("plaintext")
+ .out(header(HeaderNames.Server, STATIC_SERVER_NAME))
+ .out(stringBody)
+ .zServerLogic { _ =>
+ ZIO.succeed(plainTextMessage)
+ }
+
+ val jsonRoute: ZServerEndpoint[Any, Any] =
+ endpoint.get.in("json")
+ .out(header(HeaderNames.Server, STATIC_SERVER_NAME))
+ .out(jsonBody[Payload])
+ .zServerLogic { _ =>
+ ZIO.succeed(Payload(plainTextMessage))
+ }
+
+ val app = ZioHttpInterpreter().toHttp(List(plaintextRoute, jsonRoute))
+
+
+ val config = Server.Config.default
+ .port(8080)
+ .enableRequestStreaming
+
+ val nettyConfig = NettyConfig.default
+ .leakDetection(LeakDetectionLevel.DISABLED)
+ .maxThreads(NUM_PROCESSORS)
+
+ val configLayer = ZLayer.succeed(config)
+ val nettyConfigLayer = ZLayer.succeed(nettyConfig)
+
+ Server.serve(app).provide(configLayer, nettyConfigLayer, Server.customized).exitCode
+ }
+}
\ No newline at end of file
From abec3b99a82e1421902b90aa3d090d51226ad038 Mon Sep 17 00:00:00 2001
From: Alpha Ho <666504+alphaho@users.noreply.github.com>
Date: Sat, 12 Apr 2025 22:32:53 +0900
Subject: [PATCH 2/7] upgrade zio-http to 3.2.0
---
frameworks/Scala/zio-http/build.sbt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frameworks/Scala/zio-http/build.sbt b/frameworks/Scala/zio-http/build.sbt
index a985d9b5dc9..d1b92381715 100644
--- a/frameworks/Scala/zio-http/build.sbt
+++ b/frameworks/Scala/zio-http/build.sbt
@@ -3,7 +3,7 @@ version := "1.0.0"
scalaVersion := "2.13.14"
lazy val root = (project in file("."))
.settings(
- libraryDependencies += "dev.zio" %% "zio-http" % "3.0.0-RC10",
+ libraryDependencies += "dev.zio" %% "zio-http" % "3.2.0",
testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework"),
assembly / assemblyMergeStrategy := {
case x if x.contains("io.netty.versions.properties") => MergeStrategy.discard
From 4bea78bc7620cd0b827f204894969e663f2e2852 Mon Sep 17 00:00:00 2001
From: Alpha Ho <666504+alphaho@users.noreply.github.com>
Date: Sat, 12 Apr 2025 22:36:03 +0900
Subject: [PATCH 3/7] fix: update zio-http to adhere to the json test
requirement
That is "For each request, an object mapping the key message to Hello, World! must be instantiated."
---
frameworks/Scala/zio-http/src/main/scala/Main.scala | 5 +++--
frameworks/Scala/zio-http/src/main/scala/Payload.scala | 6 ++++++
2 files changed, 9 insertions(+), 2 deletions(-)
create mode 100644 frameworks/Scala/zio-http/src/main/scala/Payload.scala
diff --git a/frameworks/Scala/zio-http/src/main/scala/Main.scala b/frameworks/Scala/zio-http/src/main/scala/Main.scala
index 8af102fd7f6..652a4a43357 100644
--- a/frameworks/Scala/zio-http/src/main/scala/Main.scala
+++ b/frameworks/Scala/zio-http/src/main/scala/Main.scala
@@ -2,12 +2,13 @@ import zio._
import zio.http._
import zio.http.netty.NettyConfig
import zio.http.netty.NettyConfig.LeakDetectionLevel
+import zio.json.EncoderOps
+
import java.lang.{Runtime => JRuntime}
object Main extends ZIOAppDefault {
private val plainTextMessage: String = "hello, world!"
- private val jsonMessage: String = """{"message": "hello, world!"}"""
private val STATIC_SERVER_NAME = "zio-http"
private val NUM_PROCESSORS = JRuntime.getRuntime.availableProcessors()
@@ -22,7 +23,7 @@ object Main extends ZIOAppDefault {
Method.GET / "/json" ->
Handler.fromResponse(
Response
- .json(jsonMessage)
+ .json(Payload(plainTextMessage).toJson)
.addHeader(Header.Server(STATIC_SERVER_NAME)),
),
)
diff --git a/frameworks/Scala/zio-http/src/main/scala/Payload.scala b/frameworks/Scala/zio-http/src/main/scala/Payload.scala
new file mode 100644
index 00000000000..86b4fc705d7
--- /dev/null
+++ b/frameworks/Scala/zio-http/src/main/scala/Payload.scala
@@ -0,0 +1,6 @@
+import zio.json.{DeriveJsonCodec, JsonCodec}
+
+case class Payload(message: String)
+object Payload {
+ implicit val codec: JsonCodec[Payload] = DeriveJsonCodec.gen
+}
\ No newline at end of file
From 7775613706e16a4dab73503c7c7ae340b21e8f18 Mon Sep 17 00:00:00 2001
From: Alpha Ho <666504+alphaho@users.noreply.github.com>
Date: Sun, 13 Apr 2025 10:21:51 +0900
Subject: [PATCH 4/7] upgrade zio-http to use Java 21
---
frameworks/Scala/zio-http/README.md | 2 +-
frameworks/Scala/zio-http/build.sbt | 2 +-
frameworks/Scala/zio-http/zio-http.dockerfile | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/frameworks/Scala/zio-http/README.md b/frameworks/Scala/zio-http/README.md
index b5ea957391f..e9eb2759004 100644
--- a/frameworks/Scala/zio-http/README.md
+++ b/frameworks/Scala/zio-http/README.md
@@ -9,7 +9,7 @@ This is the ZIO Http portion of a [benchmarking test suite](../) comparing a var
## Versions
-* [Java OpenJDK 11](https://openjdk.java.net/)
+* [Java OpenJDK 21](https://openjdk.java.net/)
## Test URLs
diff --git a/frameworks/Scala/zio-http/build.sbt b/frameworks/Scala/zio-http/build.sbt
index d1b92381715..4c0157b1354 100644
--- a/frameworks/Scala/zio-http/build.sbt
+++ b/frameworks/Scala/zio-http/build.sbt
@@ -1,6 +1,6 @@
name := "zio-http"
version := "1.0.0"
-scalaVersion := "2.13.14"
+scalaVersion := "2.13.16"
lazy val root = (project in file("."))
.settings(
libraryDependencies += "dev.zio" %% "zio-http" % "3.2.0",
diff --git a/frameworks/Scala/zio-http/zio-http.dockerfile b/frameworks/Scala/zio-http/zio-http.dockerfile
index f05ead620fe..5c814e5887a 100644
--- a/frameworks/Scala/zio-http/zio-http.dockerfile
+++ b/frameworks/Scala/zio-http/zio-http.dockerfile
@@ -1,4 +1,4 @@
-FROM hseeberger/scala-sbt:11.0.12_1.5.5_2.13.6
+FROM sbtscala/scala-sbt:eclipse-temurin-21.0.6_7_1.10.11_2.13.16
WORKDIR /zhttp
COPY src src
From 9240d733053d12b0316ca984f56b6eb214cbf994 Mon Sep 17 00:00:00 2001
From: Alpha Ho <666504+alphaho@users.noreply.github.com>
Date: Sun, 13 Apr 2025 10:24:00 +0900
Subject: [PATCH 5/7] Add kyo-scheduler variants of zio-http and http4s
---
frameworks/Scala/kyo-scheduler/README.md | 24 ++++
.../Scala/kyo-scheduler/benchmark_config.json | 49 ++++++++
frameworks/Scala/kyo-scheduler/build.sbt | 54 ++++++++
frameworks/Scala/kyo-scheduler/config.toml | 32 +++++
.../src/main/resources/application.properties | 4 +
.../http4s/src/main/resources/logback.xml | 14 +++
.../benchmark/DatabaseService.scala | 71 +++++++++++
.../techempower/benchmark/WebServer.scala | 118 ++++++++++++++++++
.../http4s/src/main/twirl/index.scala.html | 14 +++
.../kyo-scheduler-http4s.dockerfile | 24 ++++
.../kyo-scheduler/kyo-scheduler.dockerfile | 10 ++
.../kyo-scheduler/project/build.properties | 1 +
.../Scala/kyo-scheduler/project/plugins.sbt | 2 +
.../zio-http/src/main/scala/Payload.scala | 6 +
.../zio-http/src/main/scala/ZioHttp.scala | 45 +++++++
15 files changed, 468 insertions(+)
create mode 100644 frameworks/Scala/kyo-scheduler/README.md
create mode 100644 frameworks/Scala/kyo-scheduler/benchmark_config.json
create mode 100644 frameworks/Scala/kyo-scheduler/build.sbt
create mode 100644 frameworks/Scala/kyo-scheduler/config.toml
create mode 100644 frameworks/Scala/kyo-scheduler/http4s/src/main/resources/application.properties
create mode 100644 frameworks/Scala/kyo-scheduler/http4s/src/main/resources/logback.xml
create mode 100644 frameworks/Scala/kyo-scheduler/http4s/src/main/scala/http4s/techempower/benchmark/DatabaseService.scala
create mode 100644 frameworks/Scala/kyo-scheduler/http4s/src/main/scala/http4s/techempower/benchmark/WebServer.scala
create mode 100644 frameworks/Scala/kyo-scheduler/http4s/src/main/twirl/index.scala.html
create mode 100644 frameworks/Scala/kyo-scheduler/kyo-scheduler-http4s.dockerfile
create mode 100644 frameworks/Scala/kyo-scheduler/kyo-scheduler.dockerfile
create mode 100644 frameworks/Scala/kyo-scheduler/project/build.properties
create mode 100644 frameworks/Scala/kyo-scheduler/project/plugins.sbt
create mode 100644 frameworks/Scala/kyo-scheduler/zio-http/src/main/scala/Payload.scala
create mode 100644 frameworks/Scala/kyo-scheduler/zio-http/src/main/scala/ZioHttp.scala
diff --git a/frameworks/Scala/kyo-scheduler/README.md b/frameworks/Scala/kyo-scheduler/README.md
new file mode 100644
index 00000000000..38244346a1f
--- /dev/null
+++ b/frameworks/Scala/kyo-scheduler/README.md
@@ -0,0 +1,24 @@
+# kyo-scheduler Benchmarking Test
+
+This is a simple test to benchmark the performance of the kyo-scheduler libraries along with different backends in Scala.
+
+### Test Type Implementation Source Code
+
+* JSON
+* PLAINTEXT
+
+## Software Versions
+
+* [Java OpenJDK 21](https://adoptium.net/temurin/releases/)
+* [Kyo 0.17.0](https://github.com/getkyo/kyo)
+* [Scala 3.6.4 and Scala 2.13.16](https://www.scala-lang.org/)
+
+### Server Implementations
+
+* [ZIO Http](https://zio.dev/zio-http/)
+* [http4s](https://http4s.org/)
+
+## Test URLs
+
+* JSON - http://localhost:8080/json
+* PLAINTEXT - http://localhost:8080/plaintext
diff --git a/frameworks/Scala/kyo-scheduler/benchmark_config.json b/frameworks/Scala/kyo-scheduler/benchmark_config.json
new file mode 100644
index 00000000000..e665c94a2fe
--- /dev/null
+++ b/frameworks/Scala/kyo-scheduler/benchmark_config.json
@@ -0,0 +1,49 @@
+{
+ "framework": "kyo-scheduler",
+ "tests": [
+ {
+ "default": {
+ "plaintext_url": "/plaintext",
+ "json_url": "/json",
+ "port": 8080,
+ "database": "None",
+ "approach": "Realistic",
+ "classification": "Micro",
+ "framework": "zio-http",
+ "language": "Scala",
+ "flavor": "None",
+ "orm": "Raw",
+ "platform": "Netty",
+ "webserver": "None",
+ "database_os": "Linux",
+ "os": "Linux",
+ "display_name": "zio-http with kyo-scheduler",
+ "notes": "https://zio.dev/zio-http/",
+ "versus": "None"
+ },
+ "http4s": {
+ "orm": "Raw",
+ "database_os": "Linux",
+ "json_url": "/json",
+ "plaintext_url": "/plaintext",
+ "query_url": "/queries?queries=",
+ "update_url": "/updates?queries=",
+ "fortune_url": "/fortunes",
+ "port": 8080,
+ "approach": "Realistic",
+ "classification": "Micro",
+ "database": "Postgres",
+ "db_url": "/db",
+ "framework": "http4s",
+ "language": "Scala",
+ "platform": "NIO2",
+ "webserver": "blaze",
+ "os": "Linux",
+ "display_name": "http4s with kyo-scheduler",
+ "notes": "https://http4s.org/",
+ "flavor": "None",
+ "versus": "None"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/frameworks/Scala/kyo-scheduler/build.sbt b/frameworks/Scala/kyo-scheduler/build.sbt
new file mode 100644
index 00000000000..1b20bc538a0
--- /dev/null
+++ b/frameworks/Scala/kyo-scheduler/build.sbt
@@ -0,0 +1,54 @@
+name := "kyo-scheduler-benchmark"
+
+ThisBuild / version := "1.0.0"
+
+val kyoVersion = "0.17.0"
+
+val commonAssemblySettings = assembly / assemblyMergeStrategy := {
+ case x if x.contains("io.netty.versions.properties") => MergeStrategy.discard
+ case x if x.contains("module-info.class") => MergeStrategy.discard
+ case x =>
+ val oldStrategy = (assembly / assemblyMergeStrategy).value
+ oldStrategy(x)
+}
+
+// based on the framework/Scala/zio-http implementation
+lazy val `zio-http` = (project in file("zio-http"))
+ .settings(
+ scalaVersion := "3.6.4",
+ name := "zio-http-kyo-scheduler-benchmark",
+ libraryDependencies ++= Seq(
+ "dev.zio" %% "zio-http" % "3.2.0",
+ "io.getkyo" %% "kyo-scheduler-zio" % kyoVersion,
+ ),
+ commonAssemblySettings
+ )
+
+val http4sVersion = "0.23.22"
+val http4sBlazeVersion = "0.23.15"
+val http4sTwirlVersion = "0.23.17"
+
+// based on the framework/Scala/http4s implementation
+lazy val http4s = (project in file("http4s"))
+ .settings(
+ scalaVersion := "2.13.16",
+ name := "http4s-kyo-scheduler-benchmark",
+ libraryDependencies ++= Seq(
+ "org.http4s" %% "http4s-blaze-server" % http4sBlazeVersion,
+ "org.http4s" %% "http4s-dsl" % http4sVersion,
+ "org.http4s" %% "http4s-twirl" % http4sTwirlVersion,
+ "org.http4s" %% "http4s-circe" % http4sVersion,
+ // Optional for auto-derivation of JSON codecs
+ "io.circe" %% "circe-generic" % "0.14.5",
+ "org.typelevel" %% "cats-effect" % "3.5.1",
+ "co.fs2" %% "fs2-core" % "3.7.0",
+ "co.fs2" %% "fs2-io" % "3.7.0",
+ "io.getquill" %% "quill-jasync-postgres" % "3.19.0",
+ "io.getquill" %% "quill-jasync" % "3.19.0",
+ "ch.qos.logback" % "logback-classic" % "1.4.8",
+ "io.getkyo" %% "kyo-scheduler-cats" % kyoVersion,
+ ),
+ commonAssemblySettings,
+ addCompilerPlugin("com.olegpy" %% "better-monadic-for" % "0.3.1")
+ )
+ .enablePlugins(SbtTwirl)
\ No newline at end of file
diff --git a/frameworks/Scala/kyo-scheduler/config.toml b/frameworks/Scala/kyo-scheduler/config.toml
new file mode 100644
index 00000000000..515c42b6557
--- /dev/null
+++ b/frameworks/Scala/kyo-scheduler/config.toml
@@ -0,0 +1,32 @@
+[framework]
+name = "kyo-scheduler"
+
+[main]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+approach = "Realistic"
+classification = "Micro"
+database = "None"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "Netty"
+webserver = "None"
+versus = "None"
+
+[http4s]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+urls.db = "/db"
+urls.query = "/queries?queries="
+urls.update = "/updates?queries="
+urls.fortune = "/fortunes"
+approach = "Realistic"
+classification = "Micro"
+database = "Postgres"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "NIO2"
+webserver = "blaze"
+versus = "None"
diff --git a/frameworks/Scala/kyo-scheduler/http4s/src/main/resources/application.properties b/frameworks/Scala/kyo-scheduler/http4s/src/main/resources/application.properties
new file mode 100644
index 00000000000..614284866be
--- /dev/null
+++ b/frameworks/Scala/kyo-scheduler/http4s/src/main/resources/application.properties
@@ -0,0 +1,4 @@
+ctx.port=5432
+ctx.username=benchmarkdbuser
+ctx.password=benchmarkdbpass
+ctx.database=hello_world
diff --git a/frameworks/Scala/kyo-scheduler/http4s/src/main/resources/logback.xml b/frameworks/Scala/kyo-scheduler/http4s/src/main/resources/logback.xml
new file mode 100644
index 00000000000..378a2fc929b
--- /dev/null
+++ b/frameworks/Scala/kyo-scheduler/http4s/src/main/resources/logback.xml
@@ -0,0 +1,14 @@
+
| id | message |
|---|---|
| @fortune.id | @fortune.message |