Browse Source

[Hexagon] Version updates, code refactor and new benchmark cases (#7754)

* Fix error with URLs in JEE servers

* Clean up

* Avoid classpath URLs

* Fix template loading error

* Fix template loading error

* Chores

* Fix template loading error

* Delete MongoDB DB support

Storage support in Hexagon will be moved outside the Toolkit, and so, it will be left outside the benchmark.

* Fix runtime problem

* Update Hexagon version

* Make Jackson Blackbird module optional

* Add variation with Blackbird module enabled

* Upgrade Hexagon version

* Enable blackbird Jackson module by default

* Update dependencies

* Use Hexagon version 2.0.0-B1 (and a little cleanup)

* Use Hexagon version 2.0.0-B1 (and a little cleanup)

* Use Tomcat instead Resin to test JEE integration

* Remove unused environment variable

* Clean Tomcat dockerfile

* Minor improvements

* Minor improvements

* Update to release version

* Update to the latest Hexagon release

* Add Netty adapter test

* Remove Gradle Wrapper

* Update version

* Update version

* Minimize template

* Skip Hexagon checks in the container

* Add Netty Epoll benchmark

* Database and template improvements

* Update Hexagon version

* Update Hexagon version

* Update DB settings

* Use a single store and template engine to simplify benchmark

* Bump mysql-connector-java in /frameworks/Java/wicket

Bumps [mysql-connector-java](https://github.com/mysql/mysql-connector-j) from 8.0.27 to 8.0.28.
- [Release notes](https://github.com/mysql/mysql-connector-j/releases)
- [Changelog](https://github.com/mysql/mysql-connector-j/blob/release/8.0/CHANGES)
- [Commits](https://github.com/mysql/mysql-connector-j/compare/8.0.27...8.0.28)

---
updated-dependencies:
- dependency-name: mysql:mysql-connector-java
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump mongodb-driver-sync from 4.2.0 to 4.2.1 in /frameworks/Java/javalin

Bumps [mongodb-driver-sync](https://github.com/mongodb/mongo-java-driver) from 4.2.0 to 4.2.1.
- [Release notes](https://github.com/mongodb/mongo-java-driver/releases)
- [Commits](https://github.com/mongodb/mongo-java-driver/compare/r4.2.0...r4.2.1)

---
updated-dependencies:
- dependency-name: org.mongodb:mongodb-driver-sync
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump ujson from 5.2.0 to 5.4.0 in /frameworks/Python/starlette

Bumps [ujson](https://github.com/ultrajson/ultrajson) from 5.2.0 to 5.4.0.
- [Release notes](https://github.com/ultrajson/ultrajson/releases)
- [Commits](https://github.com/ultrajson/ultrajson/compare/5.2.0...5.4.0)

---
updated-dependencies:
- dependency-name: ujson
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump ujson from 5.2.0 to 5.4.0 in /frameworks/Python/django

Bumps [ujson](https://github.com/ultrajson/ultrajson) from 5.2.0 to 5.4.0.
- [Release notes](https://github.com/ultrajson/ultrajson/releases)
- [Commits](https://github.com/ultrajson/ultrajson/compare/5.2.0...5.4.0)

---
updated-dependencies:
- dependency-name: ujson
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump ujson from 5.2.0 to 5.4.0 in /frameworks/Python/routerling

Bumps [ujson](https://github.com/ultrajson/ultrajson) from 5.2.0 to 5.4.0.
- [Release notes](https://github.com/ultrajson/ultrajson/releases)
- [Commits](https://github.com/ultrajson/ultrajson/compare/5.2.0...5.4.0)

---
updated-dependencies:
- dependency-name: ujson
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump ujson from 5.2.0 to 5.4.0 in /frameworks/Python/japronto

Bumps [ujson](https://github.com/ultrajson/ultrajson) from 5.2.0 to 5.4.0.
- [Release notes](https://github.com/ultrajson/ultrajson/releases)
- [Commits](https://github.com/ultrajson/ultrajson/compare/5.2.0...5.4.0)

---
updated-dependencies:
- dependency-name: ujson
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump ujson from 5.2.0 to 5.4.0 in /frameworks/Python/fastapi

Bumps [ujson](https://github.com/ultrajson/ultrajson) from 5.2.0 to 5.4.0.
- [Release notes](https://github.com/ultrajson/ultrajson/releases)
- [Commits](https://github.com/ultrajson/ultrajson/compare/5.2.0...5.4.0)

---
updated-dependencies:
- dependency-name: ujson
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump ujson from 5.2.0 to 5.4.0 in /frameworks/Python/uvicorn

Bumps [ujson](https://github.com/ultrajson/ultrajson) from 5.2.0 to 5.4.0.
- [Release notes](https://github.com/ultrajson/ultrajson/releases)
- [Commits](https://github.com/ultrajson/ultrajson/compare/5.2.0...5.4.0)

---
updated-dependencies:
- dependency-name: ujson
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump ujson from 5.2.0 to 5.4.0 in /frameworks/Python/flask

Bumps [ujson](https://github.com/ultrajson/ultrajson) from 5.2.0 to 5.4.0.
- [Release notes](https://github.com/ultrajson/ultrajson/releases)
- [Commits](https://github.com/ultrajson/ultrajson/compare/5.2.0...5.4.0)

---
updated-dependencies:
- dependency-name: ujson
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump ujson from 5.1 to 5.4.0 in /frameworks/Python/aiohttp

Bumps [ujson](https://github.com/ultrajson/ultrajson) from 5.1 to 5.4.0.
- [Release notes](https://github.com/ultrajson/ultrajson/releases)
- [Commits](https://github.com/ultrajson/ultrajson/compare/5.1.0...5.4.0)

---
updated-dependencies:
- dependency-name: ujson
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump rails-html-sanitizer from 1.4.2 to 1.4.3 in /frameworks/Ruby/rails

Bumps [rails-html-sanitizer](https://github.com/rails/rails-html-sanitizer) from 1.4.2 to 1.4.3.
- [Release notes](https://github.com/rails/rails-html-sanitizer/releases)
- [Changelog](https://github.com/rails/rails-html-sanitizer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rails/rails-html-sanitizer/compare/v1.4.2...v1.4.3)

---
updated-dependencies:
- dependency-name: rails-html-sanitizer
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump jetty-server in /frameworks/Java/jetty

Bumps [jetty-server](https://github.com/eclipse/jetty.project) from 9.4.41.v20210516 to 10.0.10.
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.41.v20210516...jetty-10.0.10)

---
updated-dependencies:
- dependency-name: org.eclipse.jetty:jetty-server
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump undertow-core in /frameworks/Java/undertow

Bumps [undertow-core](https://github.com/undertow-io/undertow) from 2.2.11.Final to 2.2.15.Final.
- [Release notes](https://github.com/undertow-io/undertow/releases)
- [Commits](https://github.com/undertow-io/undertow/compare/2.2.11.Final...2.2.15.Final)

---
updated-dependencies:
- dependency-name: io.undertow:undertow-core
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Update versions

* Update README.md

* Bump sanic from 22.3.1 to 22.6.1 in /frameworks/Python/sanic

Bumps [sanic](https://github.com/sanic-org/sanic) from 22.3.1 to 22.6.1.
- [Release notes](https://github.com/sanic-org/sanic/releases)
- [Changelog](https://github.com/sanic-org/sanic/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/sanic-org/sanic/compare/v22.3.1...v22.6.1)

---
updated-dependencies:
- dependency-name: sanic
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump postgresql from 42.3.3 to 42.4.1 in /frameworks/Java/light-java

Bumps [postgresql](https://github.com/pgjdbc/pgjdbc) from 42.3.3 to 42.4.1.
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.3.3...REL42.4.1)

---
updated-dependencies:
- dependency-name: org.postgresql:postgresql
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump postgresql from 42.3.3 to 42.4.1 in /frameworks/Java/rapidoid

Bumps [postgresql](https://github.com/pgjdbc/pgjdbc) from 42.3.3 to 42.4.1.
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.3.3...REL42.4.1)

---
updated-dependencies:
- dependency-name: org.postgresql:postgresql
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump postgresql from 42.3.3 to 42.4.1 in /frameworks/Java/jooby

Bumps [postgresql](https://github.com/pgjdbc/pgjdbc) from 42.3.3 to 42.4.1.
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.3.3...REL42.4.1)

---
updated-dependencies:
- dependency-name: org.postgresql:postgresql
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump postgresql from 42.3.3 to 42.4.1 in /frameworks/Java/servlet

Bumps [postgresql](https://github.com/pgjdbc/pgjdbc) from 42.3.3 to 42.4.1.
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.3.3...REL42.4.1)

---
updated-dependencies:
- dependency-name: org.postgresql:postgresql
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump postgresql from 42.3.3 to 42.4.1 in /frameworks/Java/spring-webflux

Bumps [postgresql](https://github.com/pgjdbc/pgjdbc) from 42.3.3 to 42.4.1.
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.3.3...REL42.4.1)

---
updated-dependencies:
- dependency-name: org.postgresql:postgresql
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump postgresql from 42.3.3 to 42.4.1 in /frameworks/Java/smart-socket

Bumps [postgresql](https://github.com/pgjdbc/pgjdbc) from 42.3.3 to 42.4.1.
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.3.3...REL42.4.1)

---
updated-dependencies:
- dependency-name: org.postgresql:postgresql
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump postgresql from 42.3.3 to 42.4.1 in /frameworks/Java/act

Bumps [postgresql](https://github.com/pgjdbc/pgjdbc) from 42.3.3 to 42.4.1.
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.3.3...REL42.4.1)

---
updated-dependencies:
- dependency-name: org.postgresql:postgresql
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump postgresql from 42.3.3 to 42.4.1 in /frameworks/Kotlin/kooby

Bumps [postgresql](https://github.com/pgjdbc/pgjdbc) from 42.3.3 to 42.4.1.
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.3.3...REL42.4.1)

---
updated-dependencies:
- dependency-name: org.postgresql:postgresql
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump postgresql from 42.3.3 to 42.4.1 in /frameworks/Java/dropwizard

Bumps [postgresql](https://github.com/pgjdbc/pgjdbc) from 42.3.3 to 42.4.1.
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.3.3...REL42.4.1)

---
updated-dependencies:
- dependency-name: org.postgresql:postgresql
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump postgresql from 42.3.3 to 42.4.1 in /frameworks/Java/hserver

Bumps [postgresql](https://github.com/pgjdbc/pgjdbc) from 42.3.3 to 42.4.1.
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.3.3...REL42.4.1)

---
updated-dependencies:
- dependency-name: org.postgresql:postgresql
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump postgresql from 42.4.0 to 42.4.1 in /frameworks/Java/undertow

Bumps [postgresql](https://github.com/pgjdbc/pgjdbc) from 42.4.0 to 42.4.1.
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.4.0...REL42.4.1)

---
updated-dependencies:
- dependency-name: org.postgresql:postgresql
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump postgresql from 42.2.23 to 42.4.1 in /frameworks/Kotlin/ktor/ktor

Bumps [postgresql](https://github.com/pgjdbc/pgjdbc) from 42.2.23 to 42.4.1.
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.2.23...REL42.4.1)

---
updated-dependencies:
- dependency-name: org.postgresql:postgresql
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Update dependencies

* Bump undertow-core in /frameworks/Java/light-java

Bumps [undertow-core](https://github.com/undertow-io/undertow) from 2.2.15.Final to 2.2.19.Final.
- [Release notes](https://github.com/undertow-io/undertow/releases)
- [Commits](https://github.com/undertow-io/undertow/compare/2.2.15.Final...2.2.19.Final)

---
updated-dependencies:
- dependency-name: io.undertow:undertow-core
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump undertow-core in /frameworks/Java/undertow

Bumps [undertow-core](https://github.com/undertow-io/undertow) from 2.2.18.Final to 2.2.19.Final.
- [Release notes](https://github.com/undertow-io/undertow/releases)
- [Commits](https://github.com/undertow-io/undertow/compare/2.2.18.Final...2.2.19.Final)

---
updated-dependencies:
- dependency-name: io.undertow:undertow-core
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Delete Gradle Wrapper

* Use different JSON serializer

* Restore non Hexagon files

* Update Hexagon version

* Run pipeline

* Run pipeline

* Bump axum-core from 0.2.7 to 0.2.8 in /frameworks/Rust/axum

Bumps [axum-core](https://github.com/tokio-rs/axum) from 0.2.7 to 0.2.8.
- [Release notes](https://github.com/tokio-rs/axum/releases)
- [Changelog](https://github.com/tokio-rs/axum/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/axum/compare/axum-core-v0.2.7...axum-core-v0.2.8)

---
updated-dependencies:
- dependency-name: axum-core
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>

* Revert "Bump axum-core from 0.2.7 to 0.2.8 in /frameworks/Rust/axum"

This reverts commit 4422de8915e70cdca67a07c2e0fdb0610757924b.

* Version updates, code refactor and new benchmark cases

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Juanjo Aguililla 2 years ago
parent
commit
784e4aff0c
28 changed files with 746 additions and 46 deletions
  1. 69 0
      frameworks/Kotlin/hexagon/benchmark_config.json
  2. 6 4
      frameworks/Kotlin/hexagon/build.gradle
  3. 54 0
      frameworks/Kotlin/hexagon/config.toml
  4. BIN
      frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar
  5. 6 0
      frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties
  6. 244 0
      frameworks/Kotlin/hexagon/gradlew
  7. 92 0
      frameworks/Kotlin/hexagon/gradlew.bat
  8. 27 0
      frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile
  9. 27 0
      frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile
  10. 5 4
      frameworks/Kotlin/hexagon/hexagon-netty.dockerfile
  11. 27 0
      frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile
  12. 5 4
      frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile
  13. 5 4
      frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile
  14. 5 4
      frameworks/Kotlin/hexagon/hexagon.dockerfile
  15. 18 2
      frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt
  16. 4 3
      frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt
  17. 0 6
      frameworks/Kotlin/hexagon/src/main/kotlin/Model.kt
  18. 1 0
      frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt
  19. 3 3
      frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt
  20. 3 0
      frameworks/Kotlin/hexagon/src/main/kotlin/model/CachedWorld.kt
  21. 3 0
      frameworks/Kotlin/hexagon/src/main/kotlin/model/Fortune.kt
  22. 3 0
      frameworks/Kotlin/hexagon/src/main/kotlin/model/Message.kt
  23. 3 0
      frameworks/Kotlin/hexagon/src/main/kotlin/model/World.kt
  24. 116 0
      frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkPgClientStore.kt
  25. 12 9
      frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt
  26. 3 3
      frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkStore.kt
  27. BIN
      frameworks/Kotlin/http4k/gradle/wrapper/gradle-wrapper.jar
  28. 5 0
      frameworks/Kotlin/http4k/gradle/wrapper/gradle-wrapper.properties

+ 69 - 0
frameworks/Kotlin/hexagon/benchmark_config.json

@@ -25,6 +25,52 @@
                 "notes": "http://hexagonkt.com",
                 "versus": "servlet"
             },
+            "jettyloom": {
+                "json_url": "/json",
+                "db_url": "/db",
+                "query_url": "/query?queries=",
+                "fortune_url": "/fortunes",
+                "update_url": "/update?queries=",
+                "cached_query_url": "/cached-queries?count=",
+                "plaintext_url": "/plaintext",
+                "port": 9090,
+                "approach": "Realistic",
+                "classification": "Micro",
+                "database": "postgres",
+                "framework": "Hexagon",
+                "language": "Kotlin",
+                "orm": "Raw",
+                "platform": "Servlet",
+                "webserver": "None",
+                "os": "Linux",
+                "database_os": "Linux",
+                "display_name": "Hexagon Jetty Loom PostgreSQL",
+                "notes": "http://hexagonkt.com",
+                "versus": "servlet"
+            },
+            "jettyloom-pgclient": {
+                "json_url": "/json",
+                "db_url": "/db",
+                "query_url": "/query?queries=",
+                "fortune_url": "/fortunes",
+                "update_url": "/update?queries=",
+                "cached_query_url": "/cached-queries?count=",
+                "plaintext_url": "/plaintext",
+                "port": 9090,
+                "approach": "Realistic",
+                "classification": "Micro",
+                "database": "postgres",
+                "framework": "Hexagon",
+                "language": "Kotlin",
+                "orm": "Raw",
+                "platform": "Servlet",
+                "webserver": "None",
+                "os": "Linux",
+                "database_os": "Linux",
+                "display_name": "Hexagon Jetty Loom PgClient",
+                "notes": "http://hexagonkt.com",
+                "versus": "servlet"
+            },
             "netty": {
                 "json_url": "/json",
                 "db_url": "/db",
@@ -71,6 +117,29 @@
                 "notes": "http://hexagonkt.com",
                 "versus": "netty"
             },
+            "nettyepoll-pgclient": {
+                "json_url": "/json",
+                "db_url": "/db",
+                "query_url": "/query?queries=",
+                "fortune_url": "/fortunes",
+                "update_url": "/update?queries=",
+                "cached_query_url": "/cached-queries?count=",
+                "plaintext_url": "/plaintext",
+                "port": 9090,
+                "approach": "Realistic",
+                "classification": "Micro",
+                "database": "postgres",
+                "framework": "Hexagon",
+                "language": "Kotlin",
+                "orm": "Raw",
+                "platform": "Netty",
+                "webserver": "None",
+                "os": "Linux",
+                "database_os": "Linux",
+                "display_name": "Hexagon Netty Epoll PgClient",
+                "notes": "http://hexagonkt.com",
+                "versus": "netty"
+            },
             "tomcat": {
                 "json_url": "/json",
                 "db_url": "/db",

+ 6 - 4
frameworks/Kotlin/hexagon/build.gradle

@@ -1,15 +1,16 @@
 
 plugins {
-    id "org.jetbrains.kotlin.jvm" version "1.7.10"
+    id "org.jetbrains.kotlin.jvm" version "1.7.22"
 }
 
 ext {
-    hexagonVersion = "2.0.23"
+    hexagonVersion = "2.2.7"
     hikariVersion = "5.0.1"
-    jettyVersion = "11.0.11"
+    jettyVersion = "11.0.12"
     postgresqlVersion = "42.5.0"
+    vertxVersion = "4.3.5"
     cache2kVersion = "2.6.1.Final"
-    nettyVersion = "4.1.80.Final"
+    nettyVersion = "4.1.85.Final"
 
     gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/$hexagonVersion/gradle"
 }
@@ -42,6 +43,7 @@ dependencies {
     implementation("org.cache2k:cache2k-core:$cache2kVersion")
     implementation("com.zaxxer:HikariCP:$hikariVersion")
     implementation("org.postgresql:postgresql:$postgresqlVersion")
+    implementation("io.vertx:vertx-pg-client:$vertxVersion")
 
     // providedCompile excludes the dependency only in the WAR, not in the distribution
     providedCompile("org.eclipse.jetty:jetty-webapp:$jettyVersion") { exclude module: "slf4j-api" }

+ 54 - 0
frameworks/Kotlin/hexagon/config.toml

@@ -19,6 +19,42 @@ platform = "Servlet"
 webserver = "None"
 versus = "servlet"
 
+[jettyloom]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+urls.db = "/db"
+urls.query = "/query?queries="
+urls.update = "/update?queries="
+urls.fortune = "/fortunes"
+urls.cached_query = "/cached-queries?count="
+approach = "Realistic"
+classification = "Micro"
+database = "postgres"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "Servlet"
+webserver = "None"
+versus = "servlet"
+
+[jettyloom-pgclient]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+urls.db = "/db"
+urls.query = "/query?queries="
+urls.update = "/update?queries="
+urls.fortune = "/fortunes"
+urls.cached_query = "/cached-queries?count="
+approach = "Realistic"
+classification = "Micro"
+database = "postgres"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "Servlet"
+webserver = "None"
+versus = "servlet"
+
 [netty]
 urls.plaintext = "/plaintext"
 urls.json = "/json"
@@ -55,6 +91,24 @@ platform = "Netty"
 webserver = "None"
 versus = "netty"
 
+[nettyepoll-pgclient]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+urls.db = "/db"
+urls.query = "/query?queries="
+urls.update = "/update?queries="
+urls.fortune = "/fortunes"
+urls.cached_query = "/cached-queries?count="
+approach = "Realistic"
+classification = "Micro"
+database = "postgres"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "Netty"
+webserver = "None"
+versus = "netty"
+
 [tomcat]
 urls.plaintext = "/plaintext"
 urls.json = "/json"

BIN
frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar


+ 6 - 0
frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,6 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https://services.gradle.org/distributions/gradle-7.6-bin.zip
+networkTimeout=10000
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists

+ 244 - 0
frameworks/Kotlin/hexagon/gradlew

@@ -0,0 +1,244 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+#   Gradle start up script for POSIX generated by Gradle.
+#
+#   Important for running:
+#
+#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+#       noncompliant, but you have some other compliant shell such as ksh or
+#       bash, then to run this script, type that shell name before the whole
+#       command line, like:
+#
+#           ksh Gradle
+#
+#       Busybox and similar reduced shells will NOT work, because this script
+#       requires all of these POSIX shell features:
+#         * functions;
+#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+#         * compound commands having a testable exit status, especially «case»;
+#         * various built-in commands including «command», «set», and «ulimit».
+#
+#   Important for patching:
+#
+#   (2) This script targets any POSIX shell, so it avoids extensions provided
+#       by Bash, Ksh, etc; in particular arrays are avoided.
+#
+#       The "traditional" practice of packing multiple parameters into a
+#       space-separated string is a well documented source of bugs and security
+#       problems, so this is (mostly) avoided, by progressively accumulating
+#       options in "$@", and eventually passing that to Java.
+#
+#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+#       see the in-line comments for details.
+#
+#       There are tweaks for specific operating systems such as AIX, CygWin,
+#       Darwin, MinGW, and NonStop.
+#
+#   (3) This script is generated from the Groovy template
+#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       within the Gradle project.
+#
+#       You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
+    [ -h "$app_path" ]
+do
+    ls=$( ls -ld "$app_path" )
+    link=${ls#*' -> '}
+    case $link in             #(
+      /*)   app_path=$link ;; #(
+      *)    app_path=$APP_HOME$link ;;
+    esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+    echo "$*"
+} >&2
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in                #(
+  CYGWIN* )         cygwin=true  ;; #(
+  Darwin* )         darwin=true  ;; #(
+  MSYS* | MINGW* )  msys=true    ;; #(
+  NONSTOP* )        nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD=$JAVA_HOME/jre/sh/java
+    else
+        JAVACMD=$JAVA_HOME/bin/java
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD=java
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+    case $MAX_FD in #(
+      max*)
+        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC3045 
+        MAX_FD=$( ulimit -H -n ) ||
+            warn "Could not query maximum file descriptor limit"
+    esac
+    case $MAX_FD in  #(
+      '' | soft) :;; #(
+      *)
+        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC3045 
+        ulimit -n "$MAX_FD" ||
+            warn "Could not set maximum file descriptor limit to $MAX_FD"
+    esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+#   * args from the command line
+#   * the main class name
+#   * -classpath
+#   * -D...appname settings
+#   * --module-path (only if needed)
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+    JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    for arg do
+        if
+            case $arg in                                #(
+              -*)   false ;;                            # don't mess with options #(
+              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
+                    [ -e "$t" ] ;;                      #(
+              *)    false ;;
+            esac
+        then
+            arg=$( cygpath --path --ignore --mixed "$arg" )
+        fi
+        # Roll the args list around exactly as many times as the number of
+        # args, so each arg winds up back in the position where it started, but
+        # possibly modified.
+        #
+        # NB: a `for` loop captures its iteration list before it begins, so
+        # changing the positional parameters here affects neither the number of
+        # iterations, nor the values presented in `arg`.
+        shift                   # remove old arg
+        set -- "$@" "$arg"      # push replacement arg
+    done
+fi
+
+# Collect all arguments for the java command;
+#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+#     shell script including quotes and variable substitutions, so put them in
+#     double quotes to make sure that they get re-expanded; and
+#   * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+        "-Dorg.gradle.appname=$APP_BASE_NAME" \
+        -classpath "$CLASSPATH" \
+        org.gradle.wrapper.GradleWrapperMain \
+        "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+    die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+#   set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+        xargs -n1 |
+        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+        tr '\n' ' '
+    )" '"$@"'
+
+exec "$JAVACMD" "$@"

+ 92 - 0
frameworks/Kotlin/hexagon/gradlew.bat

@@ -0,0 +1,92 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 27 - 0
frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile

@@ -0,0 +1,27 @@
+#
+# BUILD
+#
+FROM gradle:7.5.1-jdk17-alpine AS build
+USER root
+WORKDIR /hexagon
+
+COPY src src
+COPY build.gradle build.gradle
+RUN gradle --quiet -x test
+
+#
+# RUNTIME
+#
+FROM eclipse-temurin:19-jre-alpine
+ENV DBSTORE pg_client
+ENV POSTGRESQL_DB_HOST tfb-database
+ENV WEBENGINE jetty_loom
+ENV PROJECT hexagon
+ENV DISABLE_CHECKS true
+ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA
+
+COPY --from=build /hexagon/build/install/$PROJECT /opt/$PROJECT
+
+EXPOSE 9090
+
+ENTRYPOINT /opt/$PROJECT/bin/$PROJECT

+ 27 - 0
frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile

@@ -0,0 +1,27 @@
+#
+# BUILD
+#
+FROM gradle:7.5.1-jdk17-alpine AS build
+USER root
+WORKDIR /hexagon
+
+COPY src src
+COPY build.gradle build.gradle
+RUN gradle --quiet -x test
+
+#
+# RUNTIME
+#
+FROM eclipse-temurin:19-jre-alpine
+ENV DBSTORE postgresql
+ENV POSTGRESQL_DB_HOST tfb-database
+ENV WEBENGINE jetty_loom
+ENV PROJECT hexagon
+ENV DISABLE_CHECKS true
+ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA
+
+COPY --from=build /hexagon/build/install/$PROJECT /opt/$PROJECT
+
+EXPOSE 9090
+
+ENTRYPOINT /opt/$PROJECT/bin/$PROJECT

+ 5 - 4
frameworks/Kotlin/hexagon/hexagon-netty.dockerfile

@@ -1,25 +1,26 @@
 #
 # BUILD
 #
-FROM gradle:7.5.0-jdk17-alpine AS gradle_build
+FROM gradle:7.5.1-jdk17-alpine AS build
 USER root
 WORKDIR /hexagon
 
 COPY src src
 COPY build.gradle build.gradle
-RUN gradle --quiet
+RUN gradle --quiet -x test
 
 #
 # RUNTIME
 #
-FROM eclipse-temurin:17-jre-alpine
+FROM eclipse-temurin:19-jre-alpine
 ENV DBSTORE postgresql
 ENV POSTGRESQL_DB_HOST tfb-database
 ENV WEBENGINE netty
 ENV PROJECT hexagon
 ENV DISABLE_CHECKS true
+ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA
 
-COPY --from=gradle_build /hexagon/build/install/$PROJECT /opt/$PROJECT
+COPY --from=build /hexagon/build/install/$PROJECT /opt/$PROJECT
 
 EXPOSE 9090
 

+ 27 - 0
frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile

@@ -0,0 +1,27 @@
+#
+# BUILD
+#
+FROM gradle:7.5.1-jdk17-alpine AS build
+USER root
+WORKDIR /hexagon
+
+COPY src src
+COPY build.gradle build.gradle
+RUN gradle --quiet -x test
+
+#
+# RUNTIME
+#
+FROM eclipse-temurin:19-jre-alpine
+ENV DBSTORE pg_client
+ENV POSTGRESQL_DB_HOST tfb-database
+ENV WEBENGINE netty_epoll
+ENV PROJECT hexagon
+ENV DISABLE_CHECKS true
+ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA
+
+COPY --from=build /hexagon/build/install/$PROJECT /opt/$PROJECT
+
+EXPOSE 9090
+
+ENTRYPOINT /opt/$PROJECT/bin/$PROJECT

+ 5 - 4
frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile

@@ -1,25 +1,26 @@
 #
 # BUILD
 #
-FROM gradle:7.5.0-jdk17-alpine AS gradle_build
+FROM gradle:7.5.1-jdk17-alpine AS build
 USER root
 WORKDIR /hexagon
 
 COPY src src
 COPY build.gradle build.gradle
-RUN gradle --quiet
+RUN gradle --quiet -x test
 
 #
 # RUNTIME
 #
-FROM eclipse-temurin:17-jre-alpine
+FROM eclipse-temurin:19-jre-alpine
 ENV DBSTORE postgresql
 ENV POSTGRESQL_DB_HOST tfb-database
 ENV WEBENGINE netty_epoll
 ENV PROJECT hexagon
 ENV DISABLE_CHECKS true
+ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA
 
-COPY --from=gradle_build /hexagon/build/install/$PROJECT /opt/$PROJECT
+COPY --from=build /hexagon/build/install/$PROJECT /opt/$PROJECT
 
 EXPOSE 9090
 

+ 5 - 4
frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile

@@ -1,21 +1,22 @@
 #
 # BUILD
 #
-FROM gradle:7.5.0-jdk17-alpine AS gradle_build
+FROM gradle:7.5.1-jdk17-alpine AS build
 USER root
 WORKDIR /hexagon
 
 COPY src src
 COPY build.gradle build.gradle
-RUN gradle --quiet
+RUN gradle --quiet -x test
 
 #
 # RUNTIME
 #
-FROM tomcat:10.1.0-jre17-temurin
+FROM tomcat:10.1.2-jre17-temurin
 ENV DBSTORE postgresql
 ENV POSTGRESQL_DB_HOST tfb-database
 ENV DISABLE_CHECKS true
+ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA
 
-COPY --from=gradle_build /hexagon/build/libs/ROOT.war /usr/local/tomcat/webapps/ROOT.war
+COPY --from=build /hexagon/build/libs/ROOT.war /usr/local/tomcat/webapps/ROOT.war
 EXPOSE 8080

+ 5 - 4
frameworks/Kotlin/hexagon/hexagon.dockerfile

@@ -1,25 +1,26 @@
 #
 # BUILD
 #
-FROM gradle:7.5.0-jdk17-alpine AS gradle_build
+FROM gradle:7.5.1-jdk17-alpine AS build
 USER root
 WORKDIR /hexagon
 
 COPY src src
 COPY build.gradle build.gradle
-RUN gradle --quiet
+RUN gradle --quiet -x test
 
 #
 # RUNTIME
 #
-FROM eclipse-temurin:17-jre-alpine
+FROM eclipse-temurin:19-jre-alpine
 ENV DBSTORE postgresql
 ENV POSTGRESQL_DB_HOST tfb-database
 ENV WEBENGINE jetty
 ENV PROJECT hexagon
 ENV DISABLE_CHECKS true
+ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA
 
-COPY --from=gradle_build /hexagon/build/install/$PROJECT /opt/$PROJECT
+COPY --from=build /hexagon/build/install/$PROJECT /opt/$PROJECT
 
 EXPOSE 9090
 

+ 18 - 2
frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt

@@ -6,7 +6,9 @@ import com.hexagonkt.http.server.HttpServerSettings
 import com.hexagonkt.http.server.jetty.JettyServletAdapter
 import com.hexagonkt.http.server.netty.NettyServerAdapter
 import com.hexagonkt.http.server.netty.epoll.NettyEpollServerAdapter
+import com.hexagonkt.store.BenchmarkPgClientStore
 import com.hexagonkt.store.BenchmarkSqlStore
+import com.hexagonkt.store.BenchmarkStore
 import com.hexagonkt.templates.pebble.PebbleAdapter
 import java.net.InetAddress
 
@@ -19,14 +21,28 @@ private val engines: Map<String, HttpServerPort> by lazy {
             sendServerVersion = settings.sendServerVersion,
             sendXPoweredBy = settings.sendXPoweredBy,
         ),
+        "jetty_loom" to JettyServletAdapter(
+            sendDateHeader = settings.sendDateHeader,
+            sendServerVersion = settings.sendServerVersion,
+            sendXPoweredBy = settings.sendXPoweredBy,
+            useVirtualThreads = true,
+        ),
         "netty" to NettyServerAdapter(),
         "netty_epoll" to NettyEpollServerAdapter(),
     )
 }
 
-private val server: HttpServer by lazy {
+private val stores: Map<String, BenchmarkStore> by lazy {
+    mapOf(
+        "postgresql" to BenchmarkSqlStore("postgresql"),
+        "pg_client" to BenchmarkPgClientStore("postgresql"),
+    )
+}
+
+internal val server: HttpServer by lazy {
     val engine = engines[settings.webEngine] ?: error("Unsupported server engine")
-    val controller = Controller(settings, BenchmarkSqlStore("postgresql"), PebbleAdapter)
+    val store = stores[settings.dataStore] ?: error("Unsupported data store")
+    val controller = Controller(settings, store, PebbleAdapter())
     val serverSettings = HttpServerSettings(
         bindAddress = InetAddress.getByName(settings.bindAddress),
         bindPort = settings.bindPort,

+ 4 - 3
frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt

@@ -6,11 +6,12 @@ import com.hexagonkt.core.media.TextMedia.HTML
 import com.hexagonkt.core.media.TextMedia.PLAIN
 import com.hexagonkt.http.model.ContentType
 import com.hexagonkt.http.model.Header
-import com.hexagonkt.http.model.HttpFields
+import com.hexagonkt.http.model.Headers
 import com.hexagonkt.http.server.handlers.HttpServerContext
 import com.hexagonkt.http.server.handlers.PathHandler
 import com.hexagonkt.http.server.handlers.path
 import com.hexagonkt.http.toHttpFormat
+import com.hexagonkt.model.*
 import com.hexagonkt.serialization.dsl.json.Json
 import com.hexagonkt.serialization.serialize
 import com.hexagonkt.store.BenchmarkStore
@@ -37,7 +38,7 @@ class Controller(
 
     private val templateUrl: URL = URL("classpath:fortunes.pebble.html")
 
-    private val headers = HttpFields(
+    private val headers = Headers(
         Header("server", "Hexagon"),
     )
 
@@ -106,7 +107,7 @@ class Controller(
         ok(body.serialize(Json.raw), contentType = json)
 
     private fun HttpServerContext.getWorldsCount(parameter: String): Int =
-        request.queryParameters[parameter]?.toIntOrNull().let {
+        request.queryParameters[parameter]?.value?.toIntOrNull().let {
             when {
                 it == null -> 1
                 it < 1 -> 1

+ 0 - 6
frameworks/Kotlin/hexagon/src/main/kotlin/Model.kt

@@ -1,6 +0,0 @@
-package com.hexagonkt
-
-data class Message(val message: String)
-data class Fortune(val id: Int, val message: String)
-data class World(val id: Int, val randomNumber: Int)
-data class CachedWorld(val id: Int, val randomNumber: Int)

+ 1 - 0
frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt

@@ -16,6 +16,7 @@ data class Settings(
     val maximumPoolSize: Int = systemSettingOrNull("maximumPoolSize") ?: 96,
 
     val webEngine: String = systemSettingOrNull("WEBENGINE") ?: "jetty",
+    val dataStore: String = systemSettingOrNull("DATASTORE") ?: "postgresql",
 
     val worldName: String = systemSettingOrNull("worldCollection") ?: "world",
     val fortuneName: String = systemSettingOrNull("fortuneCollection") ?: "fortune",

+ 3 - 3
frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt

@@ -1,7 +1,7 @@
 package com.hexagonkt
 
 import com.hexagonkt.http.model.Header
-import com.hexagonkt.http.model.HttpFields
+import com.hexagonkt.http.model.Headers
 import com.hexagonkt.http.server.handlers.HttpHandler
 import com.hexagonkt.http.server.handlers.OnHandler
 import com.hexagonkt.http.server.servlet.ServletServer
@@ -12,10 +12,10 @@ import jakarta.servlet.annotation.WebListener
 @WebListener class WebListenerServer(settings: Settings = Settings()) : ServletServer(createHandlers(settings)) {
 
     private companion object {
-        val headers = HttpFields(Header("server", "Tomcat"))
+        val headers = Headers(Header("server", "Tomcat"))
 
         fun createHandlers(settings: Settings): List<HttpHandler> {
-            val controller = Controller(settings, BenchmarkSqlStore("postgresql"), PebbleAdapter)
+            val controller = Controller(settings, BenchmarkSqlStore("postgresql"), PebbleAdapter())
             val controllerPath = controller.path
             val serverHeaderHandler = OnHandler("*") {
                 send(headers = headers)

+ 3 - 0
frameworks/Kotlin/hexagon/src/main/kotlin/model/CachedWorld.kt

@@ -0,0 +1,3 @@
+package com.hexagonkt.model
+
+data class CachedWorld(val id: Int, val randomNumber: Int)

+ 3 - 0
frameworks/Kotlin/hexagon/src/main/kotlin/model/Fortune.kt

@@ -0,0 +1,3 @@
+package com.hexagonkt.model
+
+data class Fortune(val id: Int, val message: String)

+ 3 - 0
frameworks/Kotlin/hexagon/src/main/kotlin/model/Message.kt

@@ -0,0 +1,3 @@
+package com.hexagonkt.model
+
+data class Message(val message: String)

+ 3 - 0
frameworks/Kotlin/hexagon/src/main/kotlin/model/World.kt

@@ -0,0 +1,3 @@
+package com.hexagonkt.model
+
+data class World(val id: Int, val randomNumber: Int)

+ 116 - 0
frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkPgClientStore.kt

@@ -0,0 +1,116 @@
+package com.hexagonkt.store
+
+import com.hexagonkt.Settings
+import com.hexagonkt.core.Jvm
+import com.hexagonkt.model.CachedWorld
+import com.hexagonkt.model.Fortune
+import com.hexagonkt.model.World
+import io.vertx.core.Future
+import io.vertx.pgclient.PgConnectOptions
+import io.vertx.pgclient.PgPool
+import io.vertx.sqlclient.*
+import org.cache2k.Cache
+
+internal class BenchmarkPgClientStore(
+    engine: String, private val settings: Settings = Settings()
+) : BenchmarkStore(settings) {
+
+    companion object {
+        private const val SELECT_WORLD: String = "select * from world where id = $1"
+        private const val UPDATE_WORLD: String = "update world set randomNumber = $1 where id = $2"
+        private const val SELECT_ALL_FORTUNES: String = "select * from fortune"
+    }
+
+    private val connectOptions: PgConnectOptions by lazy {
+        PgConnectOptions().apply {
+            host = Jvm.systemSettingOrNull("${engine.uppercase()}_DB_HOST") ?: "localhost"
+            database = settings.databaseName
+            user = settings.databaseUsername
+            password = settings.databasePassword
+            cachePreparedStatements = true
+        }
+    }
+
+    private val poolOptions: PoolOptions by lazy {
+        PoolOptions().apply {
+            val environment = Jvm.systemSettingOrNull<String>("BENCHMARK_ENV")?.lowercase()
+            maxSize = 8 + if (environment == "citrine") Jvm.cpuCount else Jvm.cpuCount * 2
+        }
+    }
+
+    private val dataSource: SqlClient by lazy { PgPool.client(connectOptions, poolOptions) }
+
+    override fun findAllFortunes(): List<Fortune> =
+        dataSource.preparedQuery(SELECT_ALL_FORTUNES)
+            .execute()
+            .map { rowSet ->
+                rowSet.map { row ->
+                    Fortune(row.getInteger(0), row.getString(1))
+                }
+            }
+            .toCompletionStage()
+            .toCompletableFuture()
+            .get()
+
+    override fun findWorlds(ids: List<Int>): List<World> =
+        ids.map {
+            findWorld(it, dataSource).toCompletionStage().toCompletableFuture().get()
+        }
+
+    override fun replaceWorlds(worlds: List<World>) {
+        worlds.forEach {
+            val worldId = it.id
+            val newRandomNumber = it.randomNumber
+            dataSource
+                .preparedQuery(SELECT_WORLD)
+                .execute(Tuple.of(worldId))
+                .map { rowSet ->
+                    val row = rowSet.iterator().next()
+                    row.getInteger(1) // Read 'randomNumber' to comply with Test type 5, point 6
+                    dataSource
+                        .preparedQuery(UPDATE_WORLD)
+                        .execute(Tuple.of(newRandomNumber, worldId))
+                }
+                .toCompletionStage()
+                .toCompletableFuture()
+                .get()
+
+        }
+    }
+
+    override fun initWorldsCache(cache: Cache<Int, CachedWorld>) {
+        dataSource
+            .preparedQuery("select * from world")
+            .execute()
+            .map { rowSet ->
+                rowSet.map { row ->
+                    val id = row.getInteger(0)
+                    val randomNumber = row.getInteger(1)
+                    cache.put(id, CachedWorld(id, randomNumber))
+                }
+            }
+            .toCompletionStage()
+            .toCompletableFuture()
+            .get()
+    }
+
+    override fun loadCachedWorld(id: Int): CachedWorld =
+        findWorld(id, dataSource)
+            .map { world -> CachedWorld(world.id, world.randomNumber) }
+            .toCompletionStage()
+            .toCompletableFuture()
+            .get()
+
+    override fun close() {
+        dataSource.close()
+    }
+
+    private fun findWorld(id: Int, client: SqlClient): Future<World> =
+        client
+            .preparedQuery(SELECT_WORLD)
+            .execute(Tuple.of(id))
+            .map { rowSet ->
+                val row = rowSet.iterator().next()
+                World(row.getInteger(0), row.getInteger(1))
+            }
+}

+ 12 - 9
frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt

@@ -1,9 +1,9 @@
 package com.hexagonkt.store
 
-import com.hexagonkt.CachedWorld
-import com.hexagonkt.Fortune
+import com.hexagonkt.model.CachedWorld
+import com.hexagonkt.model.Fortune
 import com.hexagonkt.Settings
-import com.hexagonkt.World
+import com.hexagonkt.model.World
 import com.hexagonkt.core.Jvm
 import com.zaxxer.hikari.HikariConfig
 import com.zaxxer.hikari.HikariDataSource
@@ -11,13 +11,14 @@ import org.cache2k.Cache
 import java.sql.Connection
 import java.sql.PreparedStatement
 
-internal class BenchmarkSqlStore(engine: String, private val settings: Settings = Settings())
-    : BenchmarkStore(settings) {
+internal class BenchmarkSqlStore(
+    engine: String, private val settings: Settings = Settings()
+) : BenchmarkStore(settings) {
 
     companion object {
-        private const val SELECT_WORLD = "select * from world where id = ?"
-        private const val UPDATE_WORLD = "update world set randomNumber = ? where id = ?"
-        private const val SELECT_ALL_FORTUNES = "select * from fortune"
+        private const val SELECT_WORLD: String = "select * from world where id = ?"
+        private const val UPDATE_WORLD: String = "update world set randomNumber = ? where id = ?"
+        private const val SELECT_ALL_FORTUNES: String = "select * from fortune"
     }
 
     private val dataSource: HikariDataSource by lazy {
@@ -102,7 +103,9 @@ internal class BenchmarkSqlStore(engine: String, private val settings: Settings
         dataSource.close()
     }
 
-    private fun Connection.findWorld(id: Int, stmtSelect: PreparedStatement = prepareStatement(SELECT_WORLD)): World {
+    private fun Connection.findWorld(
+        id: Int, stmtSelect: PreparedStatement = prepareStatement(SELECT_WORLD)
+    ): World {
         stmtSelect.setInt(1, id)
         val rs = stmtSelect.executeQuery()
         rs.next()

+ 3 - 3
frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkStore.kt

@@ -1,9 +1,9 @@
 package com.hexagonkt.store
 
-import com.hexagonkt.CachedWorld
-import com.hexagonkt.Fortune
+import com.hexagonkt.model.CachedWorld
+import com.hexagonkt.model.Fortune
 import com.hexagonkt.Settings
-import com.hexagonkt.World
+import com.hexagonkt.model.World
 import org.cache2k.Cache
 import org.cache2k.Cache2kBuilder
 

BIN
frameworks/Kotlin/http4k/gradle/wrapper/gradle-wrapper.jar


+ 5 - 0
frameworks/Kotlin/http4k/gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists