Browse Source

Merge pull request #9604 from alphaho/kyo-tapir

Add the kyo-tapir framework
Mike Smith 5 months ago
parent
commit
f6e9246cbd

+ 21 - 0
frameworks/Scala/kyo-tapir/README.md

@@ -0,0 +1,21 @@
+# Kyo Tapir Benchmarking Test
+
+This is a simple test to benchmark the performance of the Kyo and Tapir libraries in Scala.
+
+### Test Type Implementation Source Code
+
+* [JSON](src/main/scala/Main.scala)
+* [PLAINTEXT](src/main/scala/Main.scala)
+
+## Software Versions
+
+* [Java OpenJDK 21](https://adoptium.net/temurin/releases/)
+* [Scala 3.6.3](https://www.scala-lang.org/)
+* [Kyo 0.16.2](https://github.com/getkyo/kyo)
+* [Tapir 1.11.15](https://tapir.softwaremill.com)
+* [ZIO Json 0.7.32](https://zio.dev/zio-json/)
+
+## Test URLs
+
+* JSON - http://localhost:9999/json
+* PLAINTEXT - http://localhost:9999/plaintext

+ 26 - 0
frameworks/Scala/kyo-tapir/benchmark_config.json

@@ -0,0 +1,26 @@
+{
+  "framework": "kyo-tapir",
+  "tests": [
+    {
+      "default": {
+        "plaintext_url": "/plaintext",
+        "json_url": "/json",
+        "port": 9999,
+        "database": "None",
+        "approach": "Realistic",
+        "classification": "Micro",
+        "framework": "kyo-tapir",
+        "language": "Scala",
+        "flavor": "None",
+        "orm": "Raw",
+        "platform": "Netty",
+        "webserver": "None",
+        "database_os": "Linux",
+        "os": "Linux",
+        "display_name": "kyo-tapir",
+        "notes": "",
+        "versus": "None"
+      }
+    }
+  ]
+}

+ 17 - 0
frameworks/Scala/kyo-tapir/build.sbt

@@ -0,0 +1,17 @@
+name := "kyo-tapir"
+version := "1.0.0"
+scalaVersion := "3.6.3"
+lazy val root = (project in file("."))
+  .settings(
+    libraryDependencies ++= Seq(
+      "io.getkyo" %% "kyo-tapir" % "0.16.2",
+      "com.softwaremill.sttp.tapir" %% "tapir-json-zio" % "1.11.15",
+      "dev.zio" %% "zio-json" % "0.7.32"
+    ),
+    assembly / assemblyMergeStrategy  := {
+      case x if x.contains("io.netty.versions.properties") => MergeStrategy.discard
+      case x =>
+        val oldStrategy = (assembly / assemblyMergeStrategy).value
+        oldStrategy(x)
+    }
+  )

+ 15 - 0
frameworks/Scala/kyo-tapir/config.toml

@@ -0,0 +1,15 @@
+[framework]
+name = "kyo-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"

+ 10 - 0
frameworks/Scala/kyo-tapir/kyo-tapir.dockerfile

@@ -0,0 +1,10 @@
+FROM sbtscala/scala-sbt:eclipse-temurin-21.0.6_7_1.10.7_3.6.3
+
+WORKDIR /kyo-tapir
+COPY src src
+COPY project project
+COPY build.sbt build.sbt
+RUN sbt assembly
+
+EXPOSE 9999
+CMD ["java", "-Xms2G", "-Xmx2G", "-server", "-Dio.netty.leakDetection.level=disabled", "-Dio.netty.recycler.maxCapacityPerThread=0", "-jar", "/kyo-tapir/target/scala-3.6.3/kyo-tapir-assembly-1.0.0.jar"]

+ 1 - 0
frameworks/Scala/kyo-tapir/project/build.properties

@@ -0,0 +1 @@
+sbt.version = 1.10.7

+ 1 - 0
frameworks/Scala/kyo-tapir/project/plugins.sbt

@@ -0,0 +1 @@
+addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.3.1")

+ 48 - 0
frameworks/Scala/kyo-tapir/src/main/scala/Main.scala

@@ -0,0 +1,48 @@
+import kyo.*
+import sttp.model.{Header, HeaderNames}
+import sttp.tapir.*
+import sttp.tapir.json.zio.*
+import sttp.tapir.server.netty.*
+
+object Main extends KyoApp {
+  private val STATIC_SERVER_NAME = "kyo-tapir"
+
+  private val plainTextMessage: String = "Hello, World!"
+
+  run {
+    val plaintextRoute: Unit < Routes =
+      Routes.add(
+        _.get.in("plaintext")
+          .out(header(HeaderNames.Server, STATIC_SERVER_NAME))
+          .out(header[String](HeaderNames.Date))
+          .out(stringBody)
+      ) { _ =>
+        for {
+          now <- Clock.now
+        } yield Header.toHttpDateString(now.toJava) -> plainTextMessage
+      }
+
+    val jsonRoute: Unit < Routes =
+      Routes.add(
+        _.get.in("json")
+          .out(header(HeaderNames.Server, STATIC_SERVER_NAME))
+          .out(header[String](HeaderNames.Date))
+          .out(jsonBody[Payload])
+      ) { _ =>
+        for {
+          now <- Clock.now
+        } yield Header.toHttpDateString(now.toJava) -> Payload(plainTextMessage)
+      }
+
+    val config = NettyConfig.default
+      .withSocketKeepAlive
+      .copy(lingerTimeout = None)
+    
+    val server = NettyKyoServer(config).host("0.0.0.0").port(9999)
+
+    val binding: NettyKyoServerBinding < Async =
+      Routes.run(server)(plaintextRoute.andThen(jsonRoute))
+
+    binding
+  }
+}

+ 8 - 0
frameworks/Scala/kyo-tapir/src/main/scala/Payload.scala

@@ -0,0 +1,8 @@
+import sttp.tapir.Schema
+import zio.json.*
+
+case class Payload(message: String)
+object Payload {
+  given JsonCodec[Payload] = DeriveJsonCodec.gen
+  given Schema[Payload] = Schema.derived
+}