From 12a691d8ce6754c17c782f1e85dddc3af6f54c4b Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 13 Aug 2021 17:08:53 +0200 Subject: [PATCH 001/149] Fix error with URLs in JEE servers --- frameworks/Kotlin/hexagon/build.gradle | 8 ++++---- frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt | 3 ++- .../Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index eeedb367dcf..71fce93860d 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -4,13 +4,13 @@ plugins { } ext { - gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/1.3.20/gradle" + gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/1.4.0/gradle" - hexagonVersion = "1.3.20" - hikariVersion = "4.0.3" // TODO Check with 3.4.5, 4.0.3 or 5.0.0 + hexagonVersion = "1.4.0" + hikariVersion = "5.0.0" jettyVersion = "10.0.6" postgresqlVersion = "42.2.23" - cache2kVersion = "2.0.0.Final" + cache2kVersion = "2.2.1.Final" jacksonBlackbirdVersion = "2.12.4" } diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt index 9ad9ea60fc4..8df102971de 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt @@ -6,6 +6,7 @@ import com.hexagonkt.serialization.Json import com.hexagonkt.serialization.toFieldsMap import com.hexagonkt.store.BenchmarkStore import com.hexagonkt.templates.TemplatePort +import java.net.URL import java.util.concurrent.ThreadLocalRandom class Controller(private val settings: Settings) { @@ -42,7 +43,7 @@ class Controller(private val settings: Settings) { val context = mapOf("fortunes" to sortedFortunes) response.contentType = "text/html;charset=utf-8" - ok(templateAdapter.render("fortunes.$templateKind.html", context)) + ok(templateAdapter.render(URL("classpath:fortunes.$templateKind.html"), context)) } private fun Call.dbQuery(store: BenchmarkStore) { diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt index dfdf941d3cd..b2114fdf3ff 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt @@ -10,6 +10,7 @@ import javax.servlet.annotation.WebListener @WebListener class WebListenerServer(settings: Settings = Settings()) : ServletServer(Controller(settings).router) { init { + ClasspathHandler.registerHandler() Json.mapper.registerModule(BlackbirdModule()) SerializationManager.mapper = JacksonMapper SerializationManager.formats = linkedSetOf(Json) From 5242fd2c83badadb827a8db1c48143d11f6f11d9 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 13 Aug 2021 17:33:48 +0200 Subject: [PATCH 002/149] Clean up --- frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt index b2114fdf3ff..174f5417267 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt @@ -15,6 +15,4 @@ import javax.servlet.annotation.WebListener SerializationManager.mapper = JacksonMapper SerializationManager.formats = linkedSetOf(Json) } - - val webRouter = super.router } \ No newline at end of file From 1ca6c4c0c4902ab812aab7995e87afc4e9a46cc9 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 13 Aug 2021 17:58:39 +0200 Subject: [PATCH 003/149] Avoid classpath URLs --- frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt | 8 +++++++- .../Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt | 1 - 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt index 8df102971de..e6f5107d987 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt @@ -1,5 +1,6 @@ package com.hexagonkt +import com.hexagonkt.helpers.require import com.hexagonkt.http.server.Call import com.hexagonkt.http.server.Router import com.hexagonkt.serialization.Json @@ -11,6 +12,11 @@ import java.util.concurrent.ThreadLocalRandom class Controller(private val settings: Settings) { + private val classLoader = Thread.currentThread().contextClassLoader + private val templates: Map = mapOf( + "pebble" to (classLoader.getResource("classpath:fortunes.pebble.html") ?: error("Template not found")) + ) + internal val router: Router by lazy { Router { before { @@ -43,7 +49,7 @@ class Controller(private val settings: Settings) { val context = mapOf("fortunes" to sortedFortunes) response.contentType = "text/html;charset=utf-8" - ok(templateAdapter.render(URL("classpath:fortunes.$templateKind.html"), context)) + ok(templateAdapter.render(templates.require(templateKind), context)) } private fun Call.dbQuery(store: BenchmarkStore) { diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt index 174f5417267..488388534d3 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt @@ -10,7 +10,6 @@ import javax.servlet.annotation.WebListener @WebListener class WebListenerServer(settings: Settings = Settings()) : ServletServer(Controller(settings).router) { init { - ClasspathHandler.registerHandler() Json.mapper.registerModule(BlackbirdModule()) SerializationManager.mapper = JacksonMapper SerializationManager.formats = linkedSetOf(Json) From 6f5641bb2bd9244ae13fa6104041c04395401b95 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 13 Aug 2021 18:16:39 +0200 Subject: [PATCH 004/149] Fix template loading error --- frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt index e6f5107d987..8e6d39ed8cb 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt @@ -14,7 +14,7 @@ class Controller(private val settings: Settings) { private val classLoader = Thread.currentThread().contextClassLoader private val templates: Map = mapOf( - "pebble" to (classLoader.getResource("classpath:fortunes.pebble.html") ?: error("Template not found")) + "pebble" to (classLoader.getResource("fortunes.pebble.html") ?: error("Template not found")) ) internal val router: Router by lazy { From 5fa3b6232b3e1510c6d9972290dca1bc11250a06 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 13 Aug 2021 18:28:49 +0200 Subject: [PATCH 005/149] Fix template loading error --- frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt index 8e6d39ed8cb..2e2fb70ba0f 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt @@ -12,9 +12,9 @@ import java.util.concurrent.ThreadLocalRandom class Controller(private val settings: Settings) { - private val classLoader = Thread.currentThread().contextClassLoader + private val classLoader = ClassLoader.getSystemClassLoader() private val templates: Map = mapOf( - "pebble" to (classLoader.getResource("fortunes.pebble.html") ?: error("Template not found")) + "pebble" to (classLoader.getResource("/fortunes.pebble.html") ?: error("Template not found")) ) internal val router: Router by lazy { From 6f8264fe4025c5af599350f93b34a04317bbe61e Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 13 Aug 2021 18:47:03 +0200 Subject: [PATCH 006/149] Chores --- frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt index 2e2fb70ba0f..ae49e8e5c54 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt @@ -14,7 +14,7 @@ class Controller(private val settings: Settings) { private val classLoader = ClassLoader.getSystemClassLoader() private val templates: Map = mapOf( - "pebble" to (classLoader.getResource("/fortunes.pebble.html") ?: error("Template not found")) + "pebble" to (classLoader.getResource("fortunes.pebble.html") ?: error("Template not found")) ) internal val router: Router by lazy { From c3941d1c8ebcaf2577768bd81ef55d139d6219f8 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 13 Aug 2021 19:11:46 +0200 Subject: [PATCH 007/149] Fix template loading error --- .../Kotlin/hexagon/hexagon-resin-mongodb.dockerfile | 1 + .../hexagon/hexagon-resin-postgresql.dockerfile | 1 + .../Kotlin/hexagon/src/main/kotlin/Controller.kt | 11 +++++++++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/frameworks/Kotlin/hexagon/hexagon-resin-mongodb.dockerfile b/frameworks/Kotlin/hexagon/hexagon-resin-mongodb.dockerfile index 9884c856d38..69ebbd5ecfa 100644 --- a/frameworks/Kotlin/hexagon/hexagon-resin-mongodb.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-resin-mongodb.dockerfile @@ -21,5 +21,6 @@ WORKDIR /resin RUN curl -sL $RESIN | tar xz --strip-components=1 RUN rm -rf webapps/* COPY --from=gradle_build /hexagon/build/libs/ROOT.war webapps/ROOT.war +COPY src/main/resources/fortunes.pebble.html fortunes.pebble.html EXPOSE 9090 CMD ["java", "-jar", "lib/resin.jar", "console"] diff --git a/frameworks/Kotlin/hexagon/hexagon-resin-postgresql.dockerfile b/frameworks/Kotlin/hexagon/hexagon-resin-postgresql.dockerfile index 87c1fec3f51..4c88f47740f 100644 --- a/frameworks/Kotlin/hexagon/hexagon-resin-postgresql.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-resin-postgresql.dockerfile @@ -21,5 +21,6 @@ WORKDIR /resin RUN curl -sL $RESIN | tar xz --strip-components=1 RUN rm -rf webapps/* COPY --from=gradle_build /hexagon/build/libs/ROOT.war webapps/ROOT.war +COPY src/main/resources/fortunes.pebble.html fortunes.pebble.html EXPOSE 8080 CMD ["java", "-jar", "lib/resin.jar", "console"] diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt index ae49e8e5c54..62f010c2eb2 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt @@ -12,9 +12,8 @@ import java.util.concurrent.ThreadLocalRandom class Controller(private val settings: Settings) { - private val classLoader = ClassLoader.getSystemClassLoader() private val templates: Map = mapOf( - "pebble" to (classLoader.getResource("fortunes.pebble.html") ?: error("Template not found")) + "pebble" to (urlOrNull("classpath:fortunes.pebble.html") ?: URL("file:/resin/fortunes.pebble.html")) ) internal val router: Router by lazy { @@ -84,4 +83,12 @@ class Controller(private val settings: Settings) { private fun randomWorld(): Int = ThreadLocalRandom.current().nextInt(settings.worldRows) + 1 + + private fun urlOrNull(path: String): URL? = + try { + URL(path) + } + catch (e: Exception) { + null + } } \ No newline at end of file From 4fe8ef6b71db0853018718b2270f185e0dffecad Mon Sep 17 00:00:00 2001 From: jaguililla Date: Tue, 24 Aug 2021 19:01:21 +0200 Subject: [PATCH 008/149] Delete MongoDB DB support Storage support in Hexagon will be moved outside the Toolkit, and so, it will be left outside the benchmark. --- frameworks/Kotlin/hexagon/README.md | 5 +- .../Kotlin/hexagon/benchmark_config.json | 48 +--------------- frameworks/Kotlin/hexagon/build.gradle | 5 +- frameworks/Kotlin/hexagon/config.toml | 38 +------------ .../hexagon-jetty-postgresql.dockerfile | 25 -------- .../hexagon/hexagon-resin-mongodb.dockerfile | 26 --------- ...ql.dockerfile => hexagon-resin.dockerfile} | 2 +- frameworks/Kotlin/hexagon/hexagon.dockerfile | 6 +- .../hexagon/src/main/kotlin/Benchmark.kt | 6 +- .../kotlin/store/BenchmarkMongoDbStore.kt | 57 ------------------- 10 files changed, 10 insertions(+), 208 deletions(-) delete mode 100644 frameworks/Kotlin/hexagon/hexagon-jetty-postgresql.dockerfile delete mode 100644 frameworks/Kotlin/hexagon/hexagon-resin-mongodb.dockerfile rename frameworks/Kotlin/hexagon/{hexagon-resin-postgresql.dockerfile => hexagon-resin.dockerfile} (93%) delete mode 100644 frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkMongoDbStore.kt diff --git a/frameworks/Kotlin/hexagon/README.md b/frameworks/Kotlin/hexagon/README.md index 004f35927b4..54c66442a82 100644 --- a/frameworks/Kotlin/hexagon/README.md +++ b/frameworks/Kotlin/hexagon/README.md @@ -18,10 +18,7 @@ You can run tests against any running server passing the `verify.endpoint` proje ## Test URLs -In URLs replace `${DB_ENGINE}` with one of: - -* mongodb -* postgresql +In URLs replace `${DB_ENGINE}` with: `postgresql` and `${TEMPLATE_ENGINE}` with: `pebble` diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index 424fcbb5e8a..7bca1a660ad 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -3,52 +3,6 @@ "tests": [ { "default": { - "json_url": "/json", - "db_url": "/mongodb/db", - "query_url": "/mongodb/query?queries=", - "fortune_url": "/mongodb/pebble/fortunes", - "update_url": "/mongodb/update?queries=", - "cached_query_url": "/mongodb/cached?count=", - "plaintext_url": "/plaintext", - "port": 9090, - "approach": "Realistic", - "classification": "Micro", - "database": "mongodb", - "framework": "Hexagon", - "language": "Kotlin", - "orm": "Raw", - "platform": "Servlet", - "webserver": "None", - "os": "Linux", - "database_os": "Linux", - "display_name": "Hexagon Jetty MongoDB", - "notes": "http://hexagonkt.com", - "versus": "servlet" - }, - "resin-mongodb": { - "json_url": "/json", - "db_url": "/mongodb/db", - "query_url": "/mongodb/query?queries=", - "fortune_url": "/mongodb/pebble/fortunes", - "update_url": "/mongodb/update?queries=", - "cached_query_url": "/mongodb/cached?count=", - "plaintext_url": "/plaintext", - "port": 8080, - "approach": "Realistic", - "classification": "Micro", - "database": "mongodb", - "framework": "Hexagon", - "language": "Kotlin", - "orm": "Raw", - "platform": "Servlet", - "webserver": "None", - "os": "Linux", - "database_os": "Linux", - "display_name": "Hexagon Resin MongoDB", - "notes": "http://hexagonkt.com", - "versus": "servlet" - }, - "jetty-postgresql": { "json_url": "/json", "db_url": "/postgresql/db", "query_url": "/postgresql/query?queries=", @@ -71,7 +25,7 @@ "notes": "http://hexagonkt.com", "versus": "servlet" }, - "resin-postgresql": { + "resin": { "json_url": "/json", "db_url": "/postgresql/db", "query_url": "/postgresql/query?queries=", diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 71fce93860d..ae2ce077696 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -4,9 +4,9 @@ plugins { } ext { - gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/1.4.0/gradle" + gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/1.4.1/gradle" - hexagonVersion = "1.4.0" + hexagonVersion = "1.4.1" hikariVersion = "5.0.0" jettyVersion = "10.0.6" postgresqlVersion = "42.2.23" @@ -32,7 +32,6 @@ war { installDist.dependsOn("war") dependencies { - implementation("com.hexagonkt:store_mongodb:$hexagonVersion") implementation("com.hexagonkt:http_server_jetty:$hexagonVersion") implementation("com.hexagonkt:templates_pebble:$hexagonVersion") implementation("com.hexagonkt:logging_slf4j_jul:$hexagonVersion") diff --git a/frameworks/Kotlin/hexagon/config.toml b/frameworks/Kotlin/hexagon/config.toml index c83738043be..c688baad5a8 100644 --- a/frameworks/Kotlin/hexagon/config.toml +++ b/frameworks/Kotlin/hexagon/config.toml @@ -4,24 +4,6 @@ name = "hexagon" [main] urls.plaintext = "/plaintext" urls.json = "/json" -urls.db = "/mongodb/db" -urls.query = "/mongodb/query?queries=" -urls.update = "/mongodb/update?queries=" -urls.fortune = "/mongodb/pebble/fortunes" -urls.cached_query = "/mongodb/cached?count=" -approach = "Realistic" -classification = "Micro" -database = "mongodb" -database_os = "Linux" -os = "Linux" -orm = "Raw" -platform = "Servlet" -webserver = "None" -versus = "servlet" - -[resin-postgresql] -urls.plaintext = "/plaintext" -urls.json = "/json" urls.db = "/postgresql/db" urls.query = "/postgresql/query?queries=" urls.update = "/postgresql/update?queries=" @@ -37,7 +19,7 @@ platform = "Servlet" webserver = "None" versus = "servlet" -[jetty-postgresql] +[resin] urls.plaintext = "/plaintext" urls.json = "/json" urls.db = "/postgresql/db" @@ -54,21 +36,3 @@ orm = "Raw" platform = "Servlet" webserver = "None" versus = "servlet" - -[resin-mongodb] -urls.plaintext = "/plaintext" -urls.json = "/json" -urls.db = "/mongodb/db" -urls.query = "/mongodb/query?queries=" -urls.update = "/mongodb/update?queries=" -urls.fortune = "/mongodb/pebble/fortunes" -urls.cached_query = "/mongodb/cached?count=" -approach = "Realistic" -classification = "Micro" -database = "mongodb" -database_os = "Linux" -os = "Linux" -orm = "Raw" -platform = "Servlet" -webserver = "None" -versus = "servlet" diff --git a/frameworks/Kotlin/hexagon/hexagon-jetty-postgresql.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jetty-postgresql.dockerfile deleted file mode 100644 index 08611f3b42d..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon-jetty-postgresql.dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -# -# BUILD -# -FROM gradle:7.1-jdk11 AS gradle_build -USER root -WORKDIR /hexagon - -COPY src src -COPY build.gradle build.gradle -RUN gradle --quiet --exclude-task test - -# -# RUNTIME -# -FROM adoptopenjdk:11-jre-hotspot-bionic -ENV DBSTORE postgresql -ENV POSTGRESQL_DB_HOST tfb-database -ENV WEBENGINE jetty -ENV PROJECT hexagon - -COPY --from=gradle_build /hexagon/build/install/$PROJECT /opt/$PROJECT - -EXPOSE 9090 - -ENTRYPOINT /opt/$PROJECT/bin/$PROJECT diff --git a/frameworks/Kotlin/hexagon/hexagon-resin-mongodb.dockerfile b/frameworks/Kotlin/hexagon/hexagon-resin-mongodb.dockerfile deleted file mode 100644 index 69ebbd5ecfa..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon-resin-mongodb.dockerfile +++ /dev/null @@ -1,26 +0,0 @@ -# -# BUILD -# -FROM gradle:7.1-jdk11 AS gradle_build -USER root -WORKDIR /hexagon - -COPY src src -COPY build.gradle build.gradle -RUN gradle --quiet --exclude-task test - -# -# RUNTIME -# -FROM adoptopenjdk:11-jre-hotspot-bionic -ENV DBSTORE mongodb -ENV MONGODB_DB_HOST tfb-database -ENV RESIN http://caucho.com/download/resin-4.0.65.tar.gz - -WORKDIR /resin -RUN curl -sL $RESIN | tar xz --strip-components=1 -RUN rm -rf webapps/* -COPY --from=gradle_build /hexagon/build/libs/ROOT.war webapps/ROOT.war -COPY src/main/resources/fortunes.pebble.html fortunes.pebble.html -EXPOSE 9090 -CMD ["java", "-jar", "lib/resin.jar", "console"] diff --git a/frameworks/Kotlin/hexagon/hexagon-resin-postgresql.dockerfile b/frameworks/Kotlin/hexagon/hexagon-resin.dockerfile similarity index 93% rename from frameworks/Kotlin/hexagon/hexagon-resin-postgresql.dockerfile rename to frameworks/Kotlin/hexagon/hexagon-resin.dockerfile index 4c88f47740f..7ad188cd213 100644 --- a/frameworks/Kotlin/hexagon/hexagon-resin-postgresql.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-resin.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.1-jdk11 AS gradle_build +FROM gradle:7.2-jdk11 AS gradle_build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index a846802eb3b..ad0603eb837 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.1-jdk11 AS gradle_build +FROM gradle:7.2-jdk11 AS gradle_build USER root WORKDIR /hexagon @@ -13,8 +13,8 @@ RUN gradle --quiet --exclude-task test # RUNTIME # FROM adoptopenjdk:11-jre-hotspot-bionic -ENV DBSTORE mongodb -ENV MONGODB_DB_HOST tfb-database +ENV DBSTORE postgresql +ENV POSTGRESQL_DB_HOST tfb-database ENV WEBENGINE jetty ENV PROJECT hexagon diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt index e60779051f1..8ee2a680413 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt @@ -6,7 +6,6 @@ import com.hexagonkt.http.server.ServerPort import com.hexagonkt.http.server.ServerSettings import com.hexagonkt.http.server.jetty.JettyServletAdapter import com.hexagonkt.serialization.* -import com.hexagonkt.store.BenchmarkMongoDbStore import com.hexagonkt.store.BenchmarkSqlStore import com.hexagonkt.store.BenchmarkStore import com.hexagonkt.templates.TemplatePort @@ -14,10 +13,7 @@ import com.hexagonkt.templates.pebble.PebbleAdapter import java.net.InetAddress internal val benchmarkStores: Map by lazy { - mapOf( - "mongodb" to BenchmarkMongoDbStore("mongodb"), - "postgresql" to BenchmarkSqlStore("postgresql") - ) + mapOf("postgresql" to BenchmarkSqlStore("postgresql")) } internal val benchmarkTemplateEngines: Map by lazy { diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkMongoDbStore.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkMongoDbStore.kt deleted file mode 100644 index eb0ce04612e..00000000000 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkMongoDbStore.kt +++ /dev/null @@ -1,57 +0,0 @@ -package com.hexagonkt.store - -import com.hexagonkt.CachedWorld -import com.hexagonkt.Fortune -import com.hexagonkt.Settings -import com.hexagonkt.World -import com.hexagonkt.helpers.Jvm -import com.hexagonkt.helpers.fail -import com.hexagonkt.store.mongodb.MongoDbStore -import org.cache2k.Cache - -internal class BenchmarkMongoDbStore(engine: String, private val settings: Settings = Settings()) - : BenchmarkStore(settings) { - - data class MongoDbWorld(val _id: Int, val id: Int, val randomNumber: Int) - data class MongoDbFortune(val _id: Int, val message: String) - - private val dbHost: String by lazy { Jvm.systemSetting("${engine.uppercase()}_DB_HOST") ?: "localhost" } - - private val dbUrl: String by lazy { "mongodb://$dbHost/${settings.databaseName}" } - - private val worldRepository: MongoDbStore by lazy { - MongoDbStore(MongoDbWorld::class, MongoDbWorld::_id, dbUrl, settings.worldName) - } - - private val fortuneRepository by lazy { - MongoDbStore(MongoDbFortune::class, MongoDbFortune::_id, dbUrl, settings.fortuneName) - } - - override fun findAllFortunes(): List = fortuneRepository.findAll().map { Fortune(it._id, it.message) } - - override fun findWorlds(ids: List): List = - ids.mapNotNull { worldRepository.findOne(it) }.map { World(it.id, it.randomNumber) } - - override fun replaceWorlds(worlds: List) { - worlds.forEach { - val world = worldRepository.findOne(it.id) ?: fail - val worldCopy = world.copy(randomNumber = it.randomNumber) - worldRepository.replaceOne(worldCopy) - } - } - - override fun initWorldsCache(cache: Cache) { - worldRepository.findAll().forEach { - cache.put(it.id, CachedWorld(it.id, it.randomNumber)) - } - } - - override fun loadCachedWorld(id: Int): CachedWorld = - worldRepository.findOne(id) - ?.let { world -> CachedWorld(world.id, world.randomNumber) } - ?: error("World not found: $id") - - override fun close() { - /* Not needed */ - } -} \ No newline at end of file From 55852f184390c8b7019cc0ac215b061090e7b631 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Tue, 24 Aug 2021 19:36:22 +0200 Subject: [PATCH 009/149] Fix runtime problem --- frameworks/Kotlin/hexagon/build.gradle | 1 + frameworks/Kotlin/hexagon/hexagon-resin.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon.dockerfile | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index ae2ce077696..ef7e121a996 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -32,6 +32,7 @@ war { installDist.dependsOn("war") dependencies { + implementation("org.jetbrains.kotlin:kotlin-reflect:1.5.21") // TODO Remove on 1.4.2 implementation("com.hexagonkt:http_server_jetty:$hexagonVersion") implementation("com.hexagonkt:templates_pebble:$hexagonVersion") implementation("com.hexagonkt:logging_slf4j_jul:$hexagonVersion") diff --git a/frameworks/Kotlin/hexagon/hexagon-resin.dockerfile b/frameworks/Kotlin/hexagon/hexagon-resin.dockerfile index 7ad188cd213..3bc3ddb7838 100644 --- a/frameworks/Kotlin/hexagon/hexagon-resin.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-resin.dockerfile @@ -7,7 +7,7 @@ WORKDIR /hexagon COPY src src COPY build.gradle build.gradle -RUN gradle --quiet --exclude-task test +RUN gradle --quiet # # RUNTIME diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index ad0603eb837..f40c3b93d3d 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -7,7 +7,7 @@ WORKDIR /hexagon COPY src src COPY build.gradle build.gradle -RUN gradle --quiet --exclude-task test +RUN gradle --quiet # # RUNTIME From 0046df55ebd80b8990cc9c0c8dbd6a7418ed6ed7 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Tue, 24 Aug 2021 22:25:48 +0200 Subject: [PATCH 010/149] Update Hexagon version --- frameworks/Kotlin/hexagon/build.gradle | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index ef7e121a996..70718db9f04 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -4,9 +4,9 @@ plugins { } ext { - gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/1.4.1/gradle" + gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/1.4.2/gradle" - hexagonVersion = "1.4.1" + hexagonVersion = "1.4.2" hikariVersion = "5.0.0" jettyVersion = "10.0.6" postgresqlVersion = "42.2.23" @@ -32,7 +32,6 @@ war { installDist.dependsOn("war") dependencies { - implementation("org.jetbrains.kotlin:kotlin-reflect:1.5.21") // TODO Remove on 1.4.2 implementation("com.hexagonkt:http_server_jetty:$hexagonVersion") implementation("com.hexagonkt:templates_pebble:$hexagonVersion") implementation("com.hexagonkt:logging_slf4j_jul:$hexagonVersion") From 010d153ae8ceb037c48785020c161bb8fccadc19 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 25 Aug 2021 21:27:48 +0200 Subject: [PATCH 011/149] Make Jackson Blackbird module optional --- frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt index 8ee2a680413..7a851fd0174 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt @@ -36,7 +36,8 @@ internal val benchmarkServer: Server by lazy { } fun main() { - Json.mapper.registerModule(BlackbirdModule()) + if (System.getenv().containsKey("ENABLE_BLACKBIRD")) + Json.mapper.registerModule(BlackbirdModule()) SerializationManager.mapper = JacksonMapper SerializationManager.formats = linkedSetOf(Json) From dc625615d783f6e8519ad68c9762e42d9b6c0b20 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 13 Oct 2021 21:24:21 +0200 Subject: [PATCH 012/149] Add variation with Blackbird module enabled --- .../Kotlin/hexagon/benchmark_config.json | 23 ++++++++++++++++ frameworks/Kotlin/hexagon/config.toml | 18 +++++++++++++ .../hexagon/hexagon-blackbird.dockerfile | 26 +++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 frameworks/Kotlin/hexagon/hexagon-blackbird.dockerfile diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index 7bca1a660ad..44da569131b 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -25,6 +25,29 @@ "notes": "http://hexagonkt.com", "versus": "servlet" }, + "blackbird": { + "json_url": "/json", + "db_url": "/postgresql/db", + "query_url": "/postgresql/query?queries=", + "fortune_url": "/postgresql/pebble/fortunes", + "update_url": "/postgresql/update?queries=", + "cached_query_url": "/postgresql/cached?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 PostgreSQL", + "notes": "http://hexagonkt.com", + "versus": "servlet" + }, "resin": { "json_url": "/json", "db_url": "/postgresql/db", diff --git a/frameworks/Kotlin/hexagon/config.toml b/frameworks/Kotlin/hexagon/config.toml index c688baad5a8..dfbcd24f032 100644 --- a/frameworks/Kotlin/hexagon/config.toml +++ b/frameworks/Kotlin/hexagon/config.toml @@ -19,6 +19,24 @@ platform = "Servlet" webserver = "None" versus = "servlet" +[blackbird] +urls.plaintext = "/plaintext" +urls.json = "/json" +urls.db = "/postgresql/db" +urls.query = "/postgresql/query?queries=" +urls.update = "/postgresql/update?queries=" +urls.fortune = "/postgresql/pebble/fortunes" +urls.cached_query = "/postgresql/cached?count=" +approach = "Realistic" +classification = "Micro" +database = "postgres" +database_os = "Linux" +os = "Linux" +orm = "Raw" +platform = "Servlet" +webserver = "None" +versus = "servlet" + [resin] urls.plaintext = "/plaintext" urls.json = "/json" diff --git a/frameworks/Kotlin/hexagon/hexagon-blackbird.dockerfile b/frameworks/Kotlin/hexagon/hexagon-blackbird.dockerfile new file mode 100644 index 00000000000..07d9771d2e0 --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon-blackbird.dockerfile @@ -0,0 +1,26 @@ +# +# BUILD +# +FROM gradle:7.2-jdk11 AS gradle_build +USER root +WORKDIR /hexagon + +COPY src src +COPY build.gradle build.gradle +RUN gradle --quiet + +# +# RUNTIME +# +FROM adoptopenjdk:11-jre-hotspot-bionic +ENV DBSTORE postgresql +ENV POSTGRESQL_DB_HOST tfb-database +ENV WEBENGINE jetty +ENV PROJECT hexagon +ENV ENABLE_BLACKBIRD true + +COPY --from=gradle_build /hexagon/build/install/$PROJECT /opt/$PROJECT + +EXPOSE 9090 + +ENTRYPOINT /opt/$PROJECT/bin/$PROJECT From 349756851dfc0b992846b8ea82f89754d754dc4d Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 13 Oct 2021 21:25:08 +0200 Subject: [PATCH 013/149] Upgrade Hexagon version --- frameworks/Kotlin/hexagon/build.gradle | 12 ++++++------ .../Kotlin/hexagon/src/main/kotlin/Benchmark.kt | 3 ++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 70718db9f04..64e344c8d71 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,17 +1,17 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "1.5.21" + id "org.jetbrains.kotlin.jvm" version "1.5.31" } ext { - gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/1.4.2/gradle" + gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/1.4.7/gradle" - hexagonVersion = "1.4.2" + hexagonVersion = "1.4.7" hikariVersion = "5.0.0" - jettyVersion = "10.0.6" - postgresqlVersion = "42.2.23" + jettyVersion = "10.0.7" + postgresqlVersion = "42.2.24" cache2kVersion = "2.2.1.Final" - jacksonBlackbirdVersion = "2.12.4" + jacksonBlackbirdVersion = "2.13.0" } apply(from: "$gradleScripts/kotlin.gradle") diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt index 7a851fd0174..bfa87425fe1 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt @@ -1,6 +1,7 @@ package com.hexagonkt import com.fasterxml.jackson.module.blackbird.BlackbirdModule +import com.hexagonkt.helpers.Jvm import com.hexagonkt.http.server.Server import com.hexagonkt.http.server.ServerPort import com.hexagonkt.http.server.ServerSettings @@ -36,7 +37,7 @@ internal val benchmarkServer: Server by lazy { } fun main() { - if (System.getenv().containsKey("ENABLE_BLACKBIRD")) + if (Jvm.systemFlag("ENABLE_BLACKBIRD")) Json.mapper.registerModule(BlackbirdModule()) SerializationManager.mapper = JacksonMapper SerializationManager.formats = linkedSetOf(Json) From 8a565d196bf565857556e03fecff52a94b5cceef Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 23 Dec 2021 08:36:56 +0100 Subject: [PATCH 014/149] Enable blackbird Jackson module by default --- .../Kotlin/hexagon/benchmark_config.json | 23 ---------------- frameworks/Kotlin/hexagon/config.toml | 18 ------------- .../hexagon/hexagon-blackbird.dockerfile | 26 ------------------- frameworks/Kotlin/hexagon/hexagon.dockerfile | 3 ++- 4 files changed, 2 insertions(+), 68 deletions(-) delete mode 100644 frameworks/Kotlin/hexagon/hexagon-blackbird.dockerfile diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index 44da569131b..7bca1a660ad 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -25,29 +25,6 @@ "notes": "http://hexagonkt.com", "versus": "servlet" }, - "blackbird": { - "json_url": "/json", - "db_url": "/postgresql/db", - "query_url": "/postgresql/query?queries=", - "fortune_url": "/postgresql/pebble/fortunes", - "update_url": "/postgresql/update?queries=", - "cached_query_url": "/postgresql/cached?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 PostgreSQL", - "notes": "http://hexagonkt.com", - "versus": "servlet" - }, "resin": { "json_url": "/json", "db_url": "/postgresql/db", diff --git a/frameworks/Kotlin/hexagon/config.toml b/frameworks/Kotlin/hexagon/config.toml index dfbcd24f032..c688baad5a8 100644 --- a/frameworks/Kotlin/hexagon/config.toml +++ b/frameworks/Kotlin/hexagon/config.toml @@ -19,24 +19,6 @@ platform = "Servlet" webserver = "None" versus = "servlet" -[blackbird] -urls.plaintext = "/plaintext" -urls.json = "/json" -urls.db = "/postgresql/db" -urls.query = "/postgresql/query?queries=" -urls.update = "/postgresql/update?queries=" -urls.fortune = "/postgresql/pebble/fortunes" -urls.cached_query = "/postgresql/cached?count=" -approach = "Realistic" -classification = "Micro" -database = "postgres" -database_os = "Linux" -os = "Linux" -orm = "Raw" -platform = "Servlet" -webserver = "None" -versus = "servlet" - [resin] urls.plaintext = "/plaintext" urls.json = "/json" diff --git a/frameworks/Kotlin/hexagon/hexagon-blackbird.dockerfile b/frameworks/Kotlin/hexagon/hexagon-blackbird.dockerfile deleted file mode 100644 index 07d9771d2e0..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon-blackbird.dockerfile +++ /dev/null @@ -1,26 +0,0 @@ -# -# BUILD -# -FROM gradle:7.2-jdk11 AS gradle_build -USER root -WORKDIR /hexagon - -COPY src src -COPY build.gradle build.gradle -RUN gradle --quiet - -# -# RUNTIME -# -FROM adoptopenjdk:11-jre-hotspot-bionic -ENV DBSTORE postgresql -ENV POSTGRESQL_DB_HOST tfb-database -ENV WEBENGINE jetty -ENV PROJECT hexagon -ENV ENABLE_BLACKBIRD true - -COPY --from=gradle_build /hexagon/build/install/$PROJECT /opt/$PROJECT - -EXPOSE 9090 - -ENTRYPOINT /opt/$PROJECT/bin/$PROJECT diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index f40c3b93d3d..28a74cb7352 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.2-jdk11 AS gradle_build +FROM gradle:7.3.3-jdk11 AS gradle_build USER root WORKDIR /hexagon @@ -17,6 +17,7 @@ ENV DBSTORE postgresql ENV POSTGRESQL_DB_HOST tfb-database ENV WEBENGINE jetty ENV PROJECT hexagon +ENV ENABLE_BLACKBIRD true COPY --from=gradle_build /hexagon/build/install/$PROJECT /opt/$PROJECT From 8f9854b4f51f0853838d05d9f2c0eda5a4d20b7f Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 23 Dec 2021 09:22:14 +0100 Subject: [PATCH 015/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 10 +++++----- frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt | 3 ++- .../Kotlin/hexagon/src/main/kotlin/Controller.kt | 6 +++--- frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt | 4 ++-- .../hexagon/src/main/kotlin/WebListenerServer.kt | 6 +++--- .../hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt | 4 ++-- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 64e344c8d71..a492c71f81b 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,16 +1,16 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "1.5.31" + id "org.jetbrains.kotlin.jvm" version "1.6.10" } ext { - gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/1.4.7/gradle" + gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/1.5.1/gradle" - hexagonVersion = "1.4.7" + hexagonVersion = "1.5.1" hikariVersion = "5.0.0" jettyVersion = "10.0.7" - postgresqlVersion = "42.2.24" - cache2kVersion = "2.2.1.Final" + postgresqlVersion = "42.3.1" + cache2kVersion = "2.4.1.Final" jacksonBlackbirdVersion = "2.13.0" } diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt index bfa87425fe1..2c0ab6a27de 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt @@ -1,12 +1,13 @@ package com.hexagonkt import com.fasterxml.jackson.module.blackbird.BlackbirdModule -import com.hexagonkt.helpers.Jvm +import com.hexagonkt.core.helpers.Jvm import com.hexagonkt.http.server.Server import com.hexagonkt.http.server.ServerPort import com.hexagonkt.http.server.ServerSettings import com.hexagonkt.http.server.jetty.JettyServletAdapter import com.hexagonkt.serialization.* +import com.hexagonkt.serialization.json.* import com.hexagonkt.store.BenchmarkSqlStore import com.hexagonkt.store.BenchmarkStore import com.hexagonkt.templates.TemplatePort diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt index 62f010c2eb2..e95d526691d 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt @@ -1,9 +1,9 @@ package com.hexagonkt -import com.hexagonkt.helpers.require +import com.hexagonkt.core.helpers.require import com.hexagonkt.http.server.Call import com.hexagonkt.http.server.Router -import com.hexagonkt.serialization.Json +import com.hexagonkt.serialization.json.Json import com.hexagonkt.serialization.toFieldsMap import com.hexagonkt.store.BenchmarkStore import com.hexagonkt.templates.TemplatePort @@ -91,4 +91,4 @@ class Controller(private val settings: Settings) { catch (e: Exception) { null } -} \ No newline at end of file +} diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt index 578b11b45d9..94992292acc 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt @@ -1,6 +1,6 @@ package com.hexagonkt -import com.hexagonkt.helpers.Jvm.systemSetting +import com.hexagonkt.core.helpers.Jvm.systemSetting data class Settings( val bindPort: Int = systemSetting("bindPort") ?: 9090, @@ -25,4 +25,4 @@ data class Settings( val textMessage: String = "Hello, World!", val queriesParam: String = "queries", val cachedQueriesParam: String = "count", -) \ No newline at end of file +) diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt index 488388534d3..81a912606f1 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt @@ -2,8 +2,8 @@ package com.hexagonkt import com.fasterxml.jackson.module.blackbird.BlackbirdModule import com.hexagonkt.http.server.servlet.ServletServer -import com.hexagonkt.serialization.JacksonMapper -import com.hexagonkt.serialization.Json +import com.hexagonkt.serialization.json.JacksonMapper +import com.hexagonkt.serialization.json.Json import com.hexagonkt.serialization.SerializationManager import javax.servlet.annotation.WebListener @@ -14,4 +14,4 @@ import javax.servlet.annotation.WebListener SerializationManager.mapper = JacksonMapper SerializationManager.formats = linkedSetOf(Json) } -} \ No newline at end of file +} diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt index b0fdd6f6f85..acf4e978a6a 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt @@ -4,7 +4,7 @@ import com.hexagonkt.CachedWorld import com.hexagonkt.Fortune import com.hexagonkt.Settings import com.hexagonkt.World -import com.hexagonkt.helpers.Jvm +import com.hexagonkt.core.helpers.Jvm import com.zaxxer.hikari.HikariConfig import com.zaxxer.hikari.HikariDataSource import org.cache2k.Cache @@ -100,4 +100,4 @@ internal class BenchmarkSqlStore(engine: String, private val settings: Settings rs.next() return World(rs.getInt(1), rs.getInt(2)) } -} \ No newline at end of file +} From cdf705baa769f2cfc3c6f33c2137b26041300900 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sat, 8 Jan 2022 11:26:03 +0100 Subject: [PATCH 016/149] Use Hexagon version 2.0.0-B1 (and a little cleanup) --- frameworks/Kotlin/hexagon/build.gradle | 10 +- .../hexagon/src/main/kotlin/Benchmark.kt | 39 +++--- .../hexagon/src/main/kotlin/Controller.kt | 116 +++++++++++------- .../hexagon/src/main/kotlin/Settings.kt | 4 + .../src/main/kotlin/WebListenerServer.kt | 16 +-- 5 files changed, 103 insertions(+), 82 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index a492c71f81b..a737206edd9 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -4,14 +4,13 @@ plugins { } ext { - gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/1.5.1/gradle" + gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/2.0.0-B1/gradle" - hexagonVersion = "1.5.1" + hexagonVersion = "2.0.0-B1" hikariVersion = "5.0.0" - jettyVersion = "10.0.7" + jettyVersion = "11.0.7" postgresqlVersion = "42.3.1" cache2kVersion = "2.4.1.Final" - jacksonBlackbirdVersion = "2.13.0" } apply(from: "$gradleScripts/kotlin.gradle") @@ -35,9 +34,8 @@ dependencies { implementation("com.hexagonkt:http_server_jetty:$hexagonVersion") implementation("com.hexagonkt:templates_pebble:$hexagonVersion") implementation("com.hexagonkt:logging_slf4j_jul:$hexagonVersion") - implementation("com.hexagonkt:serialization_json:$hexagonVersion") + implementation("com.hexagonkt:serialization_jackson_json:$hexagonVersion") - implementation("com.fasterxml.jackson.module:jackson-module-blackbird:$jacksonBlackbirdVersion") implementation("org.cache2k:cache2k-core:$cache2kVersion") implementation("com.zaxxer:HikariCP:$hikariVersion") implementation("org.postgresql:postgresql:$postgresqlVersion") diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt index 2c0ab6a27de..c8174411b35 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt @@ -1,47 +1,44 @@ package com.hexagonkt -import com.fasterxml.jackson.module.blackbird.BlackbirdModule -import com.hexagonkt.core.helpers.Jvm -import com.hexagonkt.http.server.Server -import com.hexagonkt.http.server.ServerPort -import com.hexagonkt.http.server.ServerSettings +import com.hexagonkt.http.server.HttpServer +import com.hexagonkt.http.server.HttpServerPort +import com.hexagonkt.http.server.HttpServerSettings import com.hexagonkt.http.server.jetty.JettyServletAdapter -import com.hexagonkt.serialization.* -import com.hexagonkt.serialization.json.* import com.hexagonkt.store.BenchmarkSqlStore import com.hexagonkt.store.BenchmarkStore import com.hexagonkt.templates.TemplatePort import com.hexagonkt.templates.pebble.PebbleAdapter import java.net.InetAddress -internal val benchmarkStores: Map by lazy { +internal val stores: Map by lazy { mapOf("postgresql" to BenchmarkSqlStore("postgresql")) } -internal val benchmarkTemplateEngines: Map by lazy { +internal val templateEngines: Map by lazy { mapOf("pebble" to PebbleAdapter) } -internal val benchmarkEngines: Map by lazy { +private val engines: Map by lazy { mapOf("jetty" to JettyServletAdapter()) } -internal val benchmarkServer: Server by lazy { +private val server: HttpServer by lazy { val settings = Settings() - val engine = benchmarkEngines[settings.webEngine] ?: error("Unsupported server engine") - val serverSettings = ServerSettings( + val engine = engines[settings.webEngine] ?: error("Unsupported server engine") + val controller = Controller(settings, stores, templateEngines) + val serverSettings = HttpServerSettings( bindAddress = InetAddress.getByName(settings.bindAddress), - bindPort = settings.bindPort + bindPort = settings.bindPort, + options = mapOf( + "sendDateHeader" to settings.sendDateHeader, + "sendServerVersion" to settings.sendServerVersion, + "sendXPoweredBy" to settings.sendXPoweredBy, + ), ) - Server(engine, Controller(settings).router, serverSettings) + HttpServer(engine, listOf(controller.path), serverSettings) } fun main() { - if (Jvm.systemFlag("ENABLE_BLACKBIRD")) - Json.mapper.registerModule(BlackbirdModule()) - SerializationManager.mapper = JacksonMapper - SerializationManager.formats = linkedSetOf(Json) - - benchmarkServer.start() + server.start() } diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt index e95d526691d..c77cc9de631 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt @@ -1,78 +1,110 @@ package com.hexagonkt import com.hexagonkt.core.helpers.require -import com.hexagonkt.http.server.Call -import com.hexagonkt.http.server.Router -import com.hexagonkt.serialization.json.Json -import com.hexagonkt.serialization.toFieldsMap +import com.hexagonkt.core.media.ApplicationMedia.JSON +import com.hexagonkt.core.media.TextMedia.HTML +import com.hexagonkt.core.media.TextMedia.PLAIN +import com.hexagonkt.http.model.ContentType +import com.hexagonkt.http.server.handlers.HttpServerContext +import com.hexagonkt.http.server.handlers.PathHandler +import com.hexagonkt.http.server.handlers.path +import com.hexagonkt.serialization.jackson.json.Json +import com.hexagonkt.serialization.serialize import com.hexagonkt.store.BenchmarkStore import com.hexagonkt.templates.TemplatePort + import java.net.URL import java.util.concurrent.ThreadLocalRandom -class Controller(private val settings: Settings) { +import kotlin.text.Charsets.UTF_8 + +internal class Controller( + settings: Settings, + stores: Map, + templateEngines: Map, +) { + private val queriesParam: String = settings.queriesParam + private val cachedQueriesParam: String = settings.cachedQueriesParam + private val worldRows: Int = settings.worldRows + + private val plain: ContentType = ContentType(PLAIN) + private val json: ContentType = ContentType(JSON) + private val html: ContentType = ContentType(HTML, charset = UTF_8) private val templates: Map = mapOf( "pebble" to (urlOrNull("classpath:fortunes.pebble.html") ?: URL("file:/resin/fortunes.pebble.html")) ) - internal val router: Router by lazy { - Router { - before { - response.headers["Server"] = "Servlet/3.1" - response.headers["Transfer-Encoding"] = "chunked" - } - - get("/plaintext") { ok(settings.textMessage, "text/plain") } - get("/json") { ok(Message(settings.textMessage), Json) } - - benchmarkStores.forEach { (storeEngine, store) -> - benchmarkTemplateEngines.forEach { (templateEngineId, templateEngine) -> - val path = "/$storeEngine/${templateEngineId}/fortunes" - - get(path) { listFortunes(store, templateEngineId, templateEngine) } + internal val path: PathHandler by lazy { + path { + get("/plaintext") { ok(settings.textMessage, contentType = plain) } + get("/json") { ok(Message(settings.textMessage).serialize(Json), contentType = json) } + + stores.forEach { (storeEngine, store) -> + path("/$storeEngine") { + templateEngines.forEach { (templateEngineId, templateEngine) -> + get("/${templateEngineId}/fortunes") { listFortunes(store, templateEngineId, templateEngine) } + } + + get("/db") { dbQuery(store) } + get("/query") { getWorlds(store) } + get("/cached") { getCachedWorlds(store) } + get("/update") { updateWorlds(store) } } - - get("/$storeEngine/db") { dbQuery(store) } - get("/$storeEngine/query") { getWorlds(store) } - get("/$storeEngine/cached") { getCachedWorlds(store) } - get("/$storeEngine/update") { updateWorlds(store) } } } } - private fun Call.listFortunes(store: BenchmarkStore, templateKind: String, templateAdapter: TemplatePort) { + private fun HttpServerContext.listFortunes( + store: BenchmarkStore, templateKind: String, templateAdapter: TemplatePort + ): HttpServerContext { val fortunes = store.findAllFortunes() + Fortune(0, "Additional fortune added at request time.") val sortedFortunes = fortunes.sortedBy { it.message } val context = mapOf("fortunes" to sortedFortunes) + val body = templateAdapter.render(templates.require(templateKind), context) - response.contentType = "text/html;charset=utf-8" - ok(templateAdapter.render(templates.require(templateKind), context)) + return ok(body, contentType = html) } - private fun Call.dbQuery(store: BenchmarkStore) { - ok(store.findWorlds(listOf(randomWorld())).first(), Json) + private fun HttpServerContext.dbQuery(store: BenchmarkStore): HttpServerContext { + val ids = listOf(randomWorld()) + val worlds = store.findWorlds(ids) + val world = worlds.first() + + return sendJson(world) } - private fun Call.getWorlds(store: BenchmarkStore) { - val ids = (1..getWorldsCount(settings.queriesParam)).map { randomWorld() } - ok(store.findWorlds(ids), Json) + private fun HttpServerContext.getWorlds(store: BenchmarkStore): HttpServerContext { + val worldsCount = getWorldsCount(queriesParam) + val ids = (1..worldsCount).map { randomWorld() } + val worlds = store.findWorlds(ids) + + return sendJson(worlds) } - private fun Call.getCachedWorlds(store: BenchmarkStore) { - val ids = (1..getWorldsCount(settings.cachedQueriesParam)).map { randomWorld() } - ok(store.findCachedWorlds(ids).map { it.toFieldsMap() }, Json) + private fun HttpServerContext.getCachedWorlds(store: BenchmarkStore): HttpServerContext { + val worldsCount = getWorldsCount(cachedQueriesParam) + val ids = (1..worldsCount).map { randomWorld() } + val worlds = store.findCachedWorlds(ids) + + return sendJson(worlds) } - private fun Call.updateWorlds(store: BenchmarkStore) { - val worlds = (1..getWorldsCount(settings.queriesParam)).map { World(randomWorld(), randomWorld()) } + private fun HttpServerContext.updateWorlds(store: BenchmarkStore): HttpServerContext { + val worldsCount = getWorldsCount(queriesParam) + val worlds = (1..worldsCount).map { World(randomWorld(), randomWorld()) } + store.replaceWorlds(worlds) - ok(worlds, Json) + + return sendJson(worlds) } - private fun Call.getWorldsCount(parameter: String): Int = - queryParametersValues[parameter]?.firstOrNull()?.toIntOrNull().let { + private fun HttpServerContext.sendJson(body: Any): HttpServerContext = + ok(body.serialize(Json), contentType = json) + + private fun HttpServerContext.getWorldsCount(parameter: String): Int = + request.queryParameters[parameter]?.toIntOrNull().let { when { it == null -> 1 it < 1 -> 1 @@ -82,7 +114,7 @@ class Controller(private val settings: Settings) { } private fun randomWorld(): Int = - ThreadLocalRandom.current().nextInt(settings.worldRows) + 1 + ThreadLocalRandom.current().nextInt(worldRows) + 1 private fun urlOrNull(path: String): URL? = try { diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt index 94992292acc..71e58b4da42 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt @@ -21,6 +21,10 @@ data class Settings( val fortuneName: String = systemSetting("fortuneCollection") ?: "fortune", val databaseName: String = systemSetting("database") ?: "hello_world", + val sendDateHeader: Boolean = systemSetting("sendDateHeader") ?: false, + val sendServerVersion: Boolean = systemSetting("sendServerVersion") ?: true, + val sendXPoweredBy: Boolean = systemSetting("sendXPoweredBy") ?: false, + val worldRows: Int = 10_000, val textMessage: String = "Hello, World!", val queriesParam: String = "queries", diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt index 81a912606f1..1c95b0881ad 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt @@ -1,17 +1,7 @@ package com.hexagonkt -import com.fasterxml.jackson.module.blackbird.BlackbirdModule import com.hexagonkt.http.server.servlet.ServletServer -import com.hexagonkt.serialization.json.JacksonMapper -import com.hexagonkt.serialization.json.Json -import com.hexagonkt.serialization.SerializationManager -import javax.servlet.annotation.WebListener +import jakarta.servlet.annotation.WebListener -@WebListener class WebListenerServer(settings: Settings = Settings()) : ServletServer(Controller(settings).router) { - - init { - Json.mapper.registerModule(BlackbirdModule()) - SerializationManager.mapper = JacksonMapper - SerializationManager.formats = linkedSetOf(Json) - } -} +@WebListener class WebListenerServer(settings: Settings = Settings()) : + ServletServer(listOf(Controller(settings, stores, templateEngines).path)) From f8236d58e88a8f2f9c96e13e59ecbafda1f19590 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sat, 8 Jan 2022 11:37:09 +0100 Subject: [PATCH 017/149] Use Hexagon version 2.0.0-B1 (and a little cleanup) --- frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt index 71e58b4da42..2506fb74e43 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt @@ -21,7 +21,7 @@ data class Settings( val fortuneName: String = systemSetting("fortuneCollection") ?: "fortune", val databaseName: String = systemSetting("database") ?: "hello_world", - val sendDateHeader: Boolean = systemSetting("sendDateHeader") ?: false, + val sendDateHeader: Boolean = systemSetting("sendDateHeader") ?: true, val sendServerVersion: Boolean = systemSetting("sendServerVersion") ?: true, val sendXPoweredBy: Boolean = systemSetting("sendXPoweredBy") ?: false, From a344738f4c806abc98693cad622fa0188b76b679 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sat, 8 Jan 2022 15:19:37 +0100 Subject: [PATCH 018/149] Use Tomcat instead Resin to test JEE integration --- frameworks/Kotlin/hexagon/README.md | 2 +- .../Kotlin/hexagon/benchmark_config.json | 4 ++-- frameworks/Kotlin/hexagon/config.toml | 2 +- ...n.dockerfile => hexagon-tomcat.dockerfile} | 8 ++------ .../hexagon/src/main/kotlin/Controller.kt | 12 ++--------- .../hexagon/src/main/kotlin/Settings.kt | 1 + .../src/main/kotlin/WebListenerServer.kt | 20 +++++++++++++++++-- .../main/kotlin/store/BenchmarkSqlStore.kt | 5 +++-- .../src/main/kotlin/store/BenchmarkStore.kt | 4 ++-- 9 files changed, 32 insertions(+), 26 deletions(-) rename frameworks/Kotlin/hexagon/{hexagon-resin.dockerfile => hexagon-tomcat.dockerfile} (61%) diff --git a/frameworks/Kotlin/hexagon/README.md b/frameworks/Kotlin/hexagon/README.md index 54c66442a82..b83921aecdc 100644 --- a/frameworks/Kotlin/hexagon/README.md +++ b/frameworks/Kotlin/hexagon/README.md @@ -31,7 +31,7 @@ and `${TEMPLATE_ENGINE}` with: `pebble` * Database updates: http://localhost:9090/${DB_ENGINE}/update * Database queries: http://localhost:9090/${DB_ENGINE}/query -### Resin +### Tomcat * JSON Encoding Test: http://localhost:8080/json * Plain Text Test: http://localhost:8080/plaintext diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index 7bca1a660ad..78527517668 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -25,7 +25,7 @@ "notes": "http://hexagonkt.com", "versus": "servlet" }, - "resin": { + "tomcat": { "json_url": "/json", "db_url": "/postgresql/db", "query_url": "/postgresql/query?queries=", @@ -44,7 +44,7 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Resin PostgreSQL", + "display_name": "Hexagon Tomcat PostgreSQL", "notes": "http://hexagonkt.com", "versus": "servlet" } diff --git a/frameworks/Kotlin/hexagon/config.toml b/frameworks/Kotlin/hexagon/config.toml index c688baad5a8..886a19b270f 100644 --- a/frameworks/Kotlin/hexagon/config.toml +++ b/frameworks/Kotlin/hexagon/config.toml @@ -19,7 +19,7 @@ platform = "Servlet" webserver = "None" versus = "servlet" -[resin] +[tomcat] urls.plaintext = "/plaintext" urls.json = "/json" urls.db = "/postgresql/db" diff --git a/frameworks/Kotlin/hexagon/hexagon-resin.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile similarity index 61% rename from frameworks/Kotlin/hexagon/hexagon-resin.dockerfile rename to frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index 3bc3ddb7838..3351663c034 100644 --- a/frameworks/Kotlin/hexagon/hexagon-resin.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -12,15 +12,11 @@ RUN gradle --quiet # # RUNTIME # -FROM adoptopenjdk:11-jre-hotspot-bionic +FROM tomcat:10.0.14-jre17-temurin ENV DBSTORE postgresql ENV POSTGRESQL_DB_HOST tfb-database -ENV RESIN http://caucho.com/download/resin-4.0.65.tar.gz -WORKDIR /resin -RUN curl -sL $RESIN | tar xz --strip-components=1 -RUN rm -rf webapps/* +WORKDIR /usr/local/tomcat COPY --from=gradle_build /hexagon/build/libs/ROOT.war webapps/ROOT.war COPY src/main/resources/fortunes.pebble.html fortunes.pebble.html EXPOSE 8080 -CMD ["java", "-jar", "lib/resin.jar", "console"] diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt index c77cc9de631..dc8045343cf 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt @@ -18,7 +18,7 @@ import java.util.concurrent.ThreadLocalRandom import kotlin.text.Charsets.UTF_8 -internal class Controller( +class Controller( settings: Settings, stores: Map, templateEngines: Map, @@ -32,7 +32,7 @@ internal class Controller( private val html: ContentType = ContentType(HTML, charset = UTF_8) private val templates: Map = mapOf( - "pebble" to (urlOrNull("classpath:fortunes.pebble.html") ?: URL("file:/resin/fortunes.pebble.html")) + "pebble" to URL("classpath:fortunes.pebble.html") ) internal val path: PathHandler by lazy { @@ -115,12 +115,4 @@ internal class Controller( private fun randomWorld(): Int = ThreadLocalRandom.current().nextInt(worldRows) + 1 - - private fun urlOrNull(path: String): URL? = - try { - URL(path) - } - catch (e: Exception) { - null - } } diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt index 2506fb74e43..148b69b62f0 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt @@ -20,6 +20,7 @@ data class Settings( val worldName: String = systemSetting("worldCollection") ?: "world", val fortuneName: String = systemSetting("fortuneCollection") ?: "fortune", val databaseName: String = systemSetting("database") ?: "hello_world", + val databaseDriver: String = systemSetting("databaseDriver") ?: "org.postgresql.Driver", val sendDateHeader: Boolean = systemSetting("sendDateHeader") ?: true, val sendServerVersion: Boolean = systemSetting("sendServerVersion") ?: true, diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt index 1c95b0881ad..ab8752055bd 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt @@ -1,7 +1,23 @@ package com.hexagonkt +import com.hexagonkt.core.helpers.multiMapOf +import com.hexagonkt.http.server.handlers.HttpHandler +import com.hexagonkt.http.server.handlers.OnHandler import com.hexagonkt.http.server.servlet.ServletServer import jakarta.servlet.annotation.WebListener -@WebListener class WebListenerServer(settings: Settings = Settings()) : - ServletServer(listOf(Controller(settings, stores, templateEngines).path)) +@WebListener class WebListenerServer(settings: Settings = Settings()) : ServletServer(createHandlers(settings)) { + + private companion object { + + fun createHandlers(settings: Settings): List { + val controller = Controller(settings, stores, templateEngines) + val controllerPath = controller.path + val serverHeaderHandler = OnHandler { + send(headers = multiMapOf("server" to "Tomcat")) + } + + return listOf(serverHeaderHandler, controllerPath) + } + } +} diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt index acf4e978a6a..d1f4ae726e3 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt @@ -27,8 +27,9 @@ internal class BenchmarkSqlStore(engine: String, private val settings: Settings val config = HikariConfig().apply { jdbcUrl = "jdbc:postgresql://$dbHost/${settings.databaseName}" maximumPoolSize = Jvm.systemSetting(Int::class, "maximumPoolSize") ?: poolSize - username = Jvm.systemSetting("databaseUsername") ?: "benchmarkdbuser" - password = Jvm.systemSetting("databasePassword") ?: "benchmarkdbpass" + driverClassName = settings.databaseDriver + username = settings.databaseUsername + password = settings.databasePassword } HikariDataSource(config) } diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkStore.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkStore.kt index 30eaeb9dfc4..2c6ce918128 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkStore.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkStore.kt @@ -7,7 +7,7 @@ import com.hexagonkt.World import org.cache2k.Cache import org.cache2k.Cache2kBuilder -internal abstract class BenchmarkStore(settings: Settings) { +abstract class BenchmarkStore(settings: Settings) { abstract fun findAllFortunes(): List abstract fun findWorlds(ids: List): List @@ -30,4 +30,4 @@ internal abstract class BenchmarkStore(settings: Settings) { fun findCachedWorlds(ids: List): List { return ids.mapNotNull { worldsCache.get(it) } } -} \ No newline at end of file +} From 06fe67aaed0de9b54242b70d93d53c4a40e14d24 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sat, 8 Jan 2022 15:53:24 +0100 Subject: [PATCH 019/149] Remove unused environment variable --- frameworks/Kotlin/hexagon/hexagon.dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index 28a74cb7352..3d1dab5fb55 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -17,7 +17,6 @@ ENV DBSTORE postgresql ENV POSTGRESQL_DB_HOST tfb-database ENV WEBENGINE jetty ENV PROJECT hexagon -ENV ENABLE_BLACKBIRD true COPY --from=gradle_build /hexagon/build/install/$PROJECT /opt/$PROJECT From 0f7fff4b78c1bcf21358b175574b4b8db41d8cd9 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sat, 8 Jan 2022 18:21:13 +0100 Subject: [PATCH 020/149] Clean Tomcat dockerfile --- frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index 3351663c034..ae472669f14 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -16,7 +16,5 @@ FROM tomcat:10.0.14-jre17-temurin ENV DBSTORE postgresql ENV POSTGRESQL_DB_HOST tfb-database -WORKDIR /usr/local/tomcat -COPY --from=gradle_build /hexagon/build/libs/ROOT.war webapps/ROOT.war -COPY src/main/resources/fortunes.pebble.html fortunes.pebble.html +COPY --from=gradle_build /hexagon/build/libs/ROOT.war /usr/local/tomcat/webapps/ROOT.war EXPOSE 8080 From 516f4c5da773165c50721c2e4e446988d2deb4cb Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sat, 8 Jan 2022 18:58:35 +0100 Subject: [PATCH 021/149] Minor improvements --- frameworks/Kotlin/hexagon/build.gradle | 4 ++-- frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt | 2 +- frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index a737206edd9..915f4a3e4e3 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -4,9 +4,9 @@ plugins { } ext { - gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/2.0.0-B1/gradle" + gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/2.0.0-B2/gradle" - hexagonVersion = "2.0.0-B1" + hexagonVersion = "2.0.0-B2" hikariVersion = "5.0.0" jettyVersion = "11.0.7" postgresqlVersion = "42.3.1" diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt index c8174411b35..00b895d74ea 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt @@ -36,7 +36,7 @@ private val server: HttpServer by lazy { ), ) - HttpServer(engine, listOf(controller.path), serverSettings) + HttpServer(engine, controller.path, serverSettings) } fun main() { diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt index dc8045343cf..8ecb1eb527f 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt @@ -38,7 +38,7 @@ class Controller( internal val path: PathHandler by lazy { path { get("/plaintext") { ok(settings.textMessage, contentType = plain) } - get("/json") { ok(Message(settings.textMessage).serialize(Json), contentType = json) } + get("/json") { ok(Message(settings.textMessage).serialize(Json.raw), contentType = json) } stores.forEach { (storeEngine, store) -> path("/$storeEngine") { @@ -101,7 +101,7 @@ class Controller( } private fun HttpServerContext.sendJson(body: Any): HttpServerContext = - ok(body.serialize(Json), contentType = json) + ok(body.serialize(Json.raw), contentType = json) private fun HttpServerContext.getWorldsCount(parameter: String): Int = request.queryParameters[parameter]?.toIntOrNull().let { From 9e4176a2da4267e5abc60362cbd620e9e1b50f6d Mon Sep 17 00:00:00 2001 From: jaguililla Date: Mon, 10 Jan 2022 15:03:37 +0100 Subject: [PATCH 022/149] Minor improvements --- frameworks/Kotlin/hexagon/build.gradle | 4 ++-- .../Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 915f4a3e4e3..43dc7c28bc4 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -4,9 +4,9 @@ plugins { } ext { - gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/2.0.0-B2/gradle" + gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/2.0.0-B3/gradle" - hexagonVersion = "2.0.0-B2" + hexagonVersion = "2.0.0-B3" hikariVersion = "5.0.0" jettyVersion = "11.0.7" postgresqlVersion = "42.3.1" diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt index ab8752055bd..0794bda5ef4 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt @@ -13,7 +13,7 @@ import jakarta.servlet.annotation.WebListener fun createHandlers(settings: Settings): List { val controller = Controller(settings, stores, templateEngines) val controllerPath = controller.path - val serverHeaderHandler = OnHandler { + val serverHeaderHandler = OnHandler("*") { send(headers = multiMapOf("server" to "Tomcat")) } From ccd6fc40d966e0eece147ed247c83f15aa854e51 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 13 Jan 2022 17:59:54 +0100 Subject: [PATCH 023/149] Update to release version --- frameworks/Kotlin/hexagon/build.gradle | 4 ++-- frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt | 2 +- frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt | 2 +- .../Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt | 2 +- .../Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 43dc7c28bc4..b8d18ca7a89 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -4,9 +4,9 @@ plugins { } ext { - gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/2.0.0-B3/gradle" + gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/2.0.0/gradle" - hexagonVersion = "2.0.0-B3" + hexagonVersion = "2.0.0" hikariVersion = "5.0.0" jettyVersion = "11.0.7" postgresqlVersion = "42.3.1" diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt index 8ecb1eb527f..71d770cbb62 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt @@ -1,6 +1,6 @@ package com.hexagonkt -import com.hexagonkt.core.helpers.require +import com.hexagonkt.core.require import com.hexagonkt.core.media.ApplicationMedia.JSON import com.hexagonkt.core.media.TextMedia.HTML import com.hexagonkt.core.media.TextMedia.PLAIN diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt index 148b69b62f0..cc1fe17ce0c 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt @@ -1,6 +1,6 @@ package com.hexagonkt -import com.hexagonkt.core.helpers.Jvm.systemSetting +import com.hexagonkt.core.Jvm.systemSetting data class Settings( val bindPort: Int = systemSetting("bindPort") ?: 9090, diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt index 0794bda5ef4..eec6f2571d3 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt @@ -1,6 +1,6 @@ package com.hexagonkt -import com.hexagonkt.core.helpers.multiMapOf +import com.hexagonkt.core.multiMapOf import com.hexagonkt.http.server.handlers.HttpHandler import com.hexagonkt.http.server.handlers.OnHandler import com.hexagonkt.http.server.servlet.ServletServer diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt index d1f4ae726e3..2c3d20939f7 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt @@ -4,7 +4,7 @@ import com.hexagonkt.CachedWorld import com.hexagonkt.Fortune import com.hexagonkt.Settings import com.hexagonkt.World -import com.hexagonkt.core.helpers.Jvm +import com.hexagonkt.core.Jvm import com.zaxxer.hikari.HikariConfig import com.zaxxer.hikari.HikariDataSource import org.cache2k.Cache From f641771f5e907f3ff0bbcbc8b025ebbd6be16727 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 26 Jan 2022 19:32:40 +0100 Subject: [PATCH 024/149] Update to the latest Hexagon release --- frameworks/Kotlin/hexagon/build.gradle | 6 ++--- .../hexagon/src/main/kotlin/Settings.kt | 22 +++++++++---------- .../main/kotlin/store/BenchmarkSqlStore.kt | 6 ++--- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index b8d18ca7a89..fe6101d4d62 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -4,10 +4,10 @@ plugins { } ext { - gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/2.0.0/gradle" + gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/2.0.2/gradle" - hexagonVersion = "2.0.0" - hikariVersion = "5.0.0" + hexagonVersion = "2.0.2" + hikariVersion = "5.0.1" jettyVersion = "11.0.7" postgresqlVersion = "42.3.1" cache2kVersion = "2.4.1.Final" diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt index cc1fe17ce0c..53b82c5181d 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt @@ -1,9 +1,9 @@ package com.hexagonkt -import com.hexagonkt.core.Jvm.systemSetting +import com.hexagonkt.core.Jvm.systemSettingOrNull data class Settings( - val bindPort: Int = systemSetting("bindPort") ?: 9090, + val bindPort: Int = systemSettingOrNull("bindPort") ?: 9090, val bindAddress: String = "0.0.0.0", val database: String = "hello_world", @@ -13,18 +13,18 @@ data class Settings( val databaseUsername: String = "benchmarkdbuser", val databasePassword: String = "benchmarkdbpass", - val maximumPoolSize: Int = systemSetting("maximumPoolSize") ?: 96, + val maximumPoolSize: Int = systemSettingOrNull("maximumPoolSize") ?: 96, - val webEngine: String = systemSetting("WEBENGINE") ?: "jetty", + val webEngine: String = systemSettingOrNull("WEBENGINE") ?: "jetty", - val worldName: String = systemSetting("worldCollection") ?: "world", - val fortuneName: String = systemSetting("fortuneCollection") ?: "fortune", - val databaseName: String = systemSetting("database") ?: "hello_world", - val databaseDriver: String = systemSetting("databaseDriver") ?: "org.postgresql.Driver", + val worldName: String = systemSettingOrNull("worldCollection") ?: "world", + val fortuneName: String = systemSettingOrNull("fortuneCollection") ?: "fortune", + val databaseName: String = systemSettingOrNull("database") ?: "hello_world", + val databaseDriver: String = systemSettingOrNull("databaseDriver") ?: "org.postgresql.Driver", - val sendDateHeader: Boolean = systemSetting("sendDateHeader") ?: true, - val sendServerVersion: Boolean = systemSetting("sendServerVersion") ?: true, - val sendXPoweredBy: Boolean = systemSetting("sendXPoweredBy") ?: false, + val sendDateHeader: Boolean = systemSettingOrNull("sendDateHeader") ?: true, + val sendServerVersion: Boolean = systemSettingOrNull("sendServerVersion") ?: true, + val sendXPoweredBy: Boolean = systemSettingOrNull("sendXPoweredBy") ?: false, val worldRows: Int = 10_000, val textMessage: String = "Hello, World!", diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt index 2c3d20939f7..3a724dd900e 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt @@ -21,12 +21,12 @@ internal class BenchmarkSqlStore(engine: String, private val settings: Settings } private val dataSource: HikariDataSource by lazy { - val dbHost = Jvm.systemSetting("${engine.uppercase()}_DB_HOST") ?: "localhost" - val environment = Jvm.systemSetting(String::class, "BENCHMARK_ENV")?.lowercase() + val dbHost = Jvm.systemSettingOrNull("${engine.uppercase()}_DB_HOST") ?: "localhost" + val environment = Jvm.systemSettingOrNull(String::class, "BENCHMARK_ENV")?.lowercase() val poolSize = 8 + if (environment == "citrine") Jvm.cpuCount else Jvm.cpuCount * 2 val config = HikariConfig().apply { jdbcUrl = "jdbc:postgresql://$dbHost/${settings.databaseName}" - maximumPoolSize = Jvm.systemSetting(Int::class, "maximumPoolSize") ?: poolSize + maximumPoolSize = Jvm.systemSettingOrNull(Int::class, "maximumPoolSize") ?: poolSize driverClassName = settings.databaseDriver username = settings.databaseUsername password = settings.databasePassword From a41e4f629de4b456b73c00c2a1f9921d1356ed9d Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 16 Feb 2022 11:32:43 +0100 Subject: [PATCH 025/149] Add Netty adapter test --- .../Kotlin/hexagon/benchmark_config.json | 25 ++++++++++++++++++- frameworks/Kotlin/hexagon/build.gradle | 11 ++++---- frameworks/Kotlin/hexagon/config.toml | 20 ++++++++++++++- .../Kotlin/hexagon/hexagon-netty.dockerfile | 25 +++++++++++++++++++ .../Kotlin/hexagon/hexagon-tomcat.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon.dockerfile | 2 +- .../hexagon/src/main/kotlin/Benchmark.kt | 18 +++++++------ .../hexagon/src/main/kotlin/Controller.kt | 12 +++++++++ .../hexagon/src/main/kotlin/Settings.kt | 4 +-- 9 files changed, 101 insertions(+), 18 deletions(-) create mode 100644 frameworks/Kotlin/hexagon/hexagon-netty.dockerfile diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index 78527517668..d7186d7d9e8 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -25,6 +25,29 @@ "notes": "http://hexagonkt.com", "versus": "servlet" }, + "netty": { + "json_url": "/json", + "db_url": "/postgresql/db", + "query_url": "/postgresql/query?queries=", + "fortune_url": "/postgresql/pebble/fortunes", + "update_url": "/postgresql/update?queries=", + "cached_query_url": "/postgresql/cached?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 PostgreSQL", + "notes": "http://hexagonkt.com", + "versus": "netty" + }, "tomcat": { "json_url": "/json", "db_url": "/postgresql/db", @@ -41,7 +64,7 @@ "language": "Kotlin", "orm": "Raw", "platform": "Servlet", - "webserver": "None", + "webserver": "Tomcat", "os": "Linux", "database_os": "Linux", "display_name": "Hexagon Tomcat PostgreSQL", diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index fe6101d4d62..dd9480a848c 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -4,13 +4,13 @@ plugins { } ext { - gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/2.0.2/gradle" + gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/2.0.3/gradle" - hexagonVersion = "2.0.2" + hexagonVersion = "2.0.3" hikariVersion = "5.0.1" - jettyVersion = "11.0.7" - postgresqlVersion = "42.3.1" - cache2kVersion = "2.4.1.Final" + jettyVersion = "11.0.8" + postgresqlVersion = "42.3.3" + cache2kVersion = "2.6.1.Final" } apply(from: "$gradleScripts/kotlin.gradle") @@ -31,6 +31,7 @@ war { installDist.dependsOn("war") dependencies { + implementation("com.hexagonkt:http_server_netty:$hexagonVersion") implementation("com.hexagonkt:http_server_jetty:$hexagonVersion") implementation("com.hexagonkt:templates_pebble:$hexagonVersion") implementation("com.hexagonkt:logging_slf4j_jul:$hexagonVersion") diff --git a/frameworks/Kotlin/hexagon/config.toml b/frameworks/Kotlin/hexagon/config.toml index 886a19b270f..91b846defad 100644 --- a/frameworks/Kotlin/hexagon/config.toml +++ b/frameworks/Kotlin/hexagon/config.toml @@ -19,6 +19,24 @@ platform = "Servlet" webserver = "None" versus = "servlet" +[netty] +urls.plaintext = "/plaintext" +urls.json = "/json" +urls.db = "/postgresql/db" +urls.query = "/postgresql/query?queries=" +urls.update = "/postgresql/update?queries=" +urls.fortune = "/postgresql/pebble/fortunes" +urls.cached_query = "/postgresql/cached?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" @@ -34,5 +52,5 @@ database_os = "Linux" os = "Linux" orm = "Raw" platform = "Servlet" -webserver = "None" +webserver = "Tomcat" versus = "servlet" diff --git a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile new file mode 100644 index 00000000000..fad88b2d257 --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile @@ -0,0 +1,25 @@ +# +# BUILD +# +FROM gradle:7.4-jdk11 AS gradle_build +USER root +WORKDIR /hexagon + +COPY src src +COPY build.gradle build.gradle +RUN gradle --quiet + +# +# RUNTIME +# +FROM adoptopenjdk:11-jre-hotspot-bionic +ENV DBSTORE postgresql +ENV POSTGRESQL_DB_HOST tfb-database +ENV WEBENGINE netty +ENV PROJECT hexagon + +COPY --from=gradle_build /hexagon/build/install/$PROJECT /opt/$PROJECT + +EXPOSE 9090 + +ENTRYPOINT /opt/$PROJECT/bin/$PROJECT diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index ae472669f14..e8ad5a4e2ec 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.2-jdk11 AS gradle_build +FROM gradle:7.4-jdk11 AS gradle_build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index 3d1dab5fb55..1c50885a34a 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.3.3-jdk11 AS gradle_build +FROM gradle:7.4-jdk11 AS gradle_build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt index 00b895d74ea..70ab0ba2cf2 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt @@ -4,12 +4,15 @@ import com.hexagonkt.http.server.HttpServer import com.hexagonkt.http.server.HttpServerPort import com.hexagonkt.http.server.HttpServerSettings import com.hexagonkt.http.server.jetty.JettyServletAdapter +import com.hexagonkt.http.server.netty.NettyServerAdapter import com.hexagonkt.store.BenchmarkSqlStore import com.hexagonkt.store.BenchmarkStore import com.hexagonkt.templates.TemplatePort import com.hexagonkt.templates.pebble.PebbleAdapter import java.net.InetAddress +internal val settings = Settings() + internal val stores: Map by lazy { mapOf("postgresql" to BenchmarkSqlStore("postgresql")) } @@ -19,21 +22,22 @@ internal val templateEngines: Map by lazy { } private val engines: Map by lazy { - mapOf("jetty" to JettyServletAdapter()) + mapOf( + "jetty" to JettyServletAdapter( + sendDateHeader = settings.sendDateHeader, + sendServerVersion = settings.sendServerVersion, + sendXPoweredBy = settings.sendXPoweredBy, + ), + "netty" to NettyServerAdapter(), + ) } private val server: HttpServer by lazy { - val settings = Settings() val engine = engines[settings.webEngine] ?: error("Unsupported server engine") val controller = Controller(settings, stores, templateEngines) val serverSettings = HttpServerSettings( bindAddress = InetAddress.getByName(settings.bindAddress), bindPort = settings.bindPort, - options = mapOf( - "sendDateHeader" to settings.sendDateHeader, - "sendServerVersion" to settings.sendServerVersion, - "sendXPoweredBy" to settings.sendXPoweredBy, - ), ) HttpServer(engine, controller.path, serverSettings) diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt index 71d770cbb62..1454f9f37cc 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt @@ -4,16 +4,19 @@ import com.hexagonkt.core.require import com.hexagonkt.core.media.ApplicationMedia.JSON import com.hexagonkt.core.media.TextMedia.HTML import com.hexagonkt.core.media.TextMedia.PLAIN +import com.hexagonkt.core.multiMapOf import com.hexagonkt.http.model.ContentType 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.serialization.jackson.json.Json import com.hexagonkt.serialization.serialize import com.hexagonkt.store.BenchmarkStore import com.hexagonkt.templates.TemplatePort import java.net.URL +import java.time.LocalDateTime.now import java.util.concurrent.ThreadLocalRandom import kotlin.text.Charsets.UTF_8 @@ -37,6 +40,15 @@ class Controller( internal val path: PathHandler by lazy { path { + on("*") { + val headers = multiMapOf( + "server" to "Hexagon", + "date" to now().toHttpFormat(), + ) + + send(headers = headers) + } + get("/plaintext") { ok(settings.textMessage, contentType = plain) } get("/json") { ok(Message(settings.textMessage).serialize(Json.raw), contentType = json) } diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt index 53b82c5181d..e5c9994f856 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt @@ -22,8 +22,8 @@ data class Settings( val databaseName: String = systemSettingOrNull("database") ?: "hello_world", val databaseDriver: String = systemSettingOrNull("databaseDriver") ?: "org.postgresql.Driver", - val sendDateHeader: Boolean = systemSettingOrNull("sendDateHeader") ?: true, - val sendServerVersion: Boolean = systemSettingOrNull("sendServerVersion") ?: true, + val sendDateHeader: Boolean = systemSettingOrNull("sendDateHeader") ?: false, + val sendServerVersion: Boolean = systemSettingOrNull("sendServerVersion") ?: false, val sendXPoweredBy: Boolean = systemSettingOrNull("sendXPoweredBy") ?: false, val worldRows: Int = 10_000, From 138c9d30c9ca1d11414fd641f4ed9c3ff005d602 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 16 Feb 2022 11:53:50 +0100 Subject: [PATCH 026/149] Remove Gradle Wrapper --- frameworks/Kotlin/hexagon/gradlew | 183 -------------------------- frameworks/Kotlin/hexagon/gradlew.bat | 103 --------------- 2 files changed, 286 deletions(-) delete mode 100755 frameworks/Kotlin/hexagon/gradlew delete mode 100644 frameworks/Kotlin/hexagon/gradlew.bat diff --git a/frameworks/Kotlin/hexagon/gradlew b/frameworks/Kotlin/hexagon/gradlew deleted file mode 100755 index 2fe81a7d95e..00000000000 --- a/frameworks/Kotlin/hexagon/gradlew +++ /dev/null @@ -1,183 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 the original author or 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 UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# 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 "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# 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 - ;; - 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" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -exec "$JAVACMD" "$@" diff --git a/frameworks/Kotlin/hexagon/gradlew.bat b/frameworks/Kotlin/hexagon/gradlew.bat deleted file mode 100644 index 62bd9b9ccef..00000000000 --- a/frameworks/Kotlin/hexagon/gradlew.bat +++ /dev/null @@ -1,103 +0,0 @@ -@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=. -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%" == "0" goto init - -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 init - -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 - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -: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 %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="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! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega From 2ca72bcf914aae64a7beafc4a093a36872626148 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 18 Feb 2022 15:43:03 +0100 Subject: [PATCH 027/149] Update version --- frameworks/Kotlin/hexagon/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index dd9480a848c..a6c80ec4975 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -4,13 +4,13 @@ plugins { } ext { - gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/2.0.3/gradle" - - hexagonVersion = "2.0.3" + hexagonVersion = "2.0.4" hikariVersion = "5.0.1" jettyVersion = "11.0.8" postgresqlVersion = "42.3.3" cache2kVersion = "2.6.1.Final" + + gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/$hexagonVersion/gradle" } apply(from: "$gradleScripts/kotlin.gradle") From 7c1e0607cf9050c4bbcb22781ea62aef269e2647 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Mon, 21 Feb 2022 20:43:06 +0100 Subject: [PATCH 028/149] Update version --- frameworks/Kotlin/hexagon/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index a6c80ec4975..b5de5912a03 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -4,7 +4,7 @@ plugins { } ext { - hexagonVersion = "2.0.4" + hexagonVersion = "2.0.5" hikariVersion = "5.0.1" jettyVersion = "11.0.8" postgresqlVersion = "42.3.3" From 5a0fe666300550792907ada2864eb694ab8af1f2 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 1 Apr 2022 08:08:23 +0200 Subject: [PATCH 029/149] Minimize template --- frameworks/Kotlin/hexagon/build.gradle | 10 ++++++++++ frameworks/Kotlin/hexagon/hexagon.dockerfile | 1 + 2 files changed, 11 insertions(+) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index b5de5912a03..50eec566d02 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -44,3 +44,13 @@ dependencies { // providedCompile excludes the dependency only in the WAR, not in the distribution providedCompile("org.eclipse.jetty:jetty-webapp:$jettyVersion") { exclude module: "slf4j-api" } } + +task("minimizeTemplate") { + doLast { + File template = file("$buildDir/resources/main/fortunes.pebble.html") + List lines = template.readLines().collect { it.trim() } + template.write(lines.join("")) + } +} + +assemble.dependsOn("minimizeTemplate") diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index 1c50885a34a..4ca671e517d 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -17,6 +17,7 @@ ENV DBSTORE postgresql ENV POSTGRESQL_DB_HOST tfb-database ENV WEBENGINE jetty ENV PROJECT hexagon +ENV DISABLE_CHECKS true COPY --from=gradle_build /hexagon/build/install/$PROJECT /opt/$PROJECT From 9c200b4391faf5fb2e2fdfaef10ad8ddae7c1db0 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Mon, 18 Apr 2022 18:38:20 +0200 Subject: [PATCH 030/149] Skip Hexagon checks in the container --- frameworks/Kotlin/hexagon/hexagon-netty.dockerfile | 1 + frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile | 1 + 2 files changed, 2 insertions(+) diff --git a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile index fad88b2d257..95f35051bc8 100644 --- a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile @@ -17,6 +17,7 @@ ENV DBSTORE postgresql ENV POSTGRESQL_DB_HOST tfb-database ENV WEBENGINE netty ENV PROJECT hexagon +ENV DISABLE_CHECKS true COPY --from=gradle_build /hexagon/build/install/$PROJECT /opt/$PROJECT diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index e8ad5a4e2ec..27b931d8626 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -15,6 +15,7 @@ RUN gradle --quiet FROM tomcat:10.0.14-jre17-temurin ENV DBSTORE postgresql ENV POSTGRESQL_DB_HOST tfb-database +ENV DISABLE_CHECKS true COPY --from=gradle_build /hexagon/build/libs/ROOT.war /usr/local/tomcat/webapps/ROOT.war EXPOSE 8080 From cf21e3c3fa9fab60dae117f3d7b87c1e90b3f83c Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 29 Apr 2022 09:19:45 +0200 Subject: [PATCH 031/149] Add Netty Epoll benchmark --- frameworks/Kotlin/hexagon/README.md | 26 ++++++++++++++++--- .../Kotlin/hexagon/benchmark_config.json | 23 ++++++++++++++++ frameworks/Kotlin/hexagon/build.gradle | 11 +++++--- frameworks/Kotlin/hexagon/config.toml | 18 +++++++++++++ .../Kotlin/hexagon/hexagon-netty.dockerfile | 4 +-- .../hexagon/hexagon-nettyepoll.dockerfile | 26 +++++++++++++++++++ .../Kotlin/hexagon/hexagon-tomcat.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon.dockerfile | 4 +-- .../hexagon/src/main/kotlin/Benchmark.kt | 2 ++ 9 files changed, 103 insertions(+), 13 deletions(-) create mode 100644 frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile diff --git a/frameworks/Kotlin/hexagon/README.md b/frameworks/Kotlin/hexagon/README.md index b83921aecdc..779811d7c31 100644 --- a/frameworks/Kotlin/hexagon/README.md +++ b/frameworks/Kotlin/hexagon/README.md @@ -6,11 +6,11 @@ of web development platforms. The test utilizes Hexagon routes, serialization an ## Tests -You can run tests against any running server passing the `verify.endpoint` project property. I.e.: -`./gradlew verify -Pverify.endpoint=http://host:1234` +You can verify the benchmarks with the following command (from the project root): +`./tfb --mode verify --test hexagon hexagon-jetty hexagon-tomcat hexagon-netty hexagon-nettyepoll` -* [Hexagon Web](src/main/kotlin/com/hexagonkt/Benchmark.kt) -* [Hexagon Storage](src/main/kotlin/com/hexagonkt/BenchmarkStorage.kt) +To run the full benchmarks locally, on the project root (not this directory) execute: +`./tfb --mode benchmark --test hexagon hexagon-jetty hexagon-tomcat hexagon-netty hexagon-nettyepoll` ## Infrastructure Software Versions @@ -31,6 +31,24 @@ and `${TEMPLATE_ENGINE}` with: `pebble` * Database updates: http://localhost:9090/${DB_ENGINE}/update * Database queries: http://localhost:9090/${DB_ENGINE}/query +### Netty + +* JSON Encoding Test: http://localhost:9090/json +* Plain Text Test: http://localhost:9090/plaintext +* Data-Store/Database Mapping Test: http://localhost:9090/${DB_ENGINE}/db?queries=5 +* Fortunes: http://localhost:9090/${DB_ENGINE}/${TEMPLATE_ENGINE}/fortunes +* Database updates: http://localhost:9090/${DB_ENGINE}/update +* Database queries: http://localhost:9090/${DB_ENGINE}/query + +### Netty Epoll + +* JSON Encoding Test: http://localhost:9090/json +* Plain Text Test: http://localhost:9090/plaintext +* Data-Store/Database Mapping Test: http://localhost:9090/${DB_ENGINE}/db?queries=5 +* Fortunes: http://localhost:9090/${DB_ENGINE}/${TEMPLATE_ENGINE}/fortunes +* Database updates: http://localhost:9090/${DB_ENGINE}/update +* Database queries: http://localhost:9090/${DB_ENGINE}/query + ### Tomcat * JSON Encoding Test: http://localhost:8080/json diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index d7186d7d9e8..aa47cabbe96 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -48,6 +48,29 @@ "notes": "http://hexagonkt.com", "versus": "netty" }, + "nettyepoll": { + "json_url": "/json", + "db_url": "/postgresql/db", + "query_url": "/postgresql/query?queries=", + "fortune_url": "/postgresql/pebble/fortunes", + "update_url": "/postgresql/update?queries=", + "cached_query_url": "/postgresql/cached?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 PostgreSQL", + "notes": "http://hexagonkt.com", + "versus": "netty" + }, "tomcat": { "json_url": "/json", "db_url": "/postgresql/db", diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 50eec566d02..a247ae755d1 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,14 +1,15 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "1.6.10" + id "org.jetbrains.kotlin.jvm" version "1.6.21" } ext { - hexagonVersion = "2.0.5" + hexagonVersion = "2.0.7" hikariVersion = "5.0.1" - jettyVersion = "11.0.8" - postgresqlVersion = "42.3.3" + jettyVersion = "11.0.9" + postgresqlVersion = "42.3.4" cache2kVersion = "2.6.1.Final" + nettyVersion = "4.1.76.Final" gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/$hexagonVersion/gradle" } @@ -32,11 +33,13 @@ installDist.dependsOn("war") dependencies { implementation("com.hexagonkt:http_server_netty:$hexagonVersion") + implementation("com.hexagonkt:http_server_netty_epoll:$hexagonVersion") implementation("com.hexagonkt:http_server_jetty:$hexagonVersion") implementation("com.hexagonkt:templates_pebble:$hexagonVersion") implementation("com.hexagonkt:logging_slf4j_jul:$hexagonVersion") implementation("com.hexagonkt:serialization_jackson_json:$hexagonVersion") + implementation("io.netty:netty-transport-native-epoll:$nettyVersion:linux-x86_64") implementation("org.cache2k:cache2k-core:$cache2kVersion") implementation("com.zaxxer:HikariCP:$hikariVersion") implementation("org.postgresql:postgresql:$postgresqlVersion") diff --git a/frameworks/Kotlin/hexagon/config.toml b/frameworks/Kotlin/hexagon/config.toml index 91b846defad..edc7c2cf9aa 100644 --- a/frameworks/Kotlin/hexagon/config.toml +++ b/frameworks/Kotlin/hexagon/config.toml @@ -37,6 +37,24 @@ platform = "Netty" webserver = "None" versus = "netty" +[nettyepoll] +urls.plaintext = "/plaintext" +urls.json = "/json" +urls.db = "/postgresql/db" +urls.query = "/postgresql/query?queries=" +urls.update = "/postgresql/update?queries=" +urls.fortune = "/postgresql/pebble/fortunes" +urls.cached_query = "/postgresql/cached?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" diff --git a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile index 95f35051bc8..3480f54996e 100644 --- a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.4-jdk11 AS gradle_build +FROM gradle:7.4.2-jdk11 AS gradle_build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN gradle --quiet # # RUNTIME # -FROM adoptopenjdk:11-jre-hotspot-bionic +FROM eclipse-temurin:17-jre-alpine ENV DBSTORE postgresql ENV POSTGRESQL_DB_HOST tfb-database ENV WEBENGINE netty diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile new file mode 100644 index 00000000000..e97878b9e9e --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile @@ -0,0 +1,26 @@ +# +# BUILD +# +FROM gradle:7.4.2-jdk11 AS gradle_build +USER root +WORKDIR /hexagon + +COPY src src +COPY build.gradle build.gradle +RUN gradle --quiet + +# +# RUNTIME +# +FROM eclipse-temurin:17-jre-alpine +ENV DBSTORE postgresql +ENV POSTGRESQL_DB_HOST tfb-database +ENV WEBENGINE netty_epoll +ENV PROJECT hexagon +ENV DISABLE_CHECKS true + +COPY --from=gradle_build /hexagon/build/install/$PROJECT /opt/$PROJECT + +EXPOSE 9090 + +ENTRYPOINT /opt/$PROJECT/bin/$PROJECT diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index 27b931d8626..682ca865413 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.4-jdk11 AS gradle_build +FROM gradle:7.4.2-jdk11 AS gradle_build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index 4ca671e517d..8742932ca3b 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.4-jdk11 AS gradle_build +FROM gradle:7.4.2-jdk11 AS gradle_build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN gradle --quiet # # RUNTIME # -FROM adoptopenjdk:11-jre-hotspot-bionic +FROM eclipse-temurin:17-jre-alpine ENV DBSTORE postgresql ENV POSTGRESQL_DB_HOST tfb-database ENV WEBENGINE jetty diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt index 70ab0ba2cf2..e86e894e1ec 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt @@ -5,6 +5,7 @@ import com.hexagonkt.http.server.HttpServerPort 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.BenchmarkSqlStore import com.hexagonkt.store.BenchmarkStore import com.hexagonkt.templates.TemplatePort @@ -29,6 +30,7 @@ private val engines: Map by lazy { sendXPoweredBy = settings.sendXPoweredBy, ), "netty" to NettyServerAdapter(), + "netty_epoll" to NettyEpollServerAdapter(), ) } From 45209e632ccb728fb23715396e2bf4faaa7ad053 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 4 May 2022 07:41:57 +0200 Subject: [PATCH 032/149] Database and template improvements --- .../hexagon/src/main/kotlin/Controller.kt | 7 ++++--- .../main/kotlin/store/BenchmarkSqlStore.kt | 20 ++++++++++++++++++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt index 1454f9f37cc..199e8588f75 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt @@ -55,7 +55,8 @@ class Controller( stores.forEach { (storeEngine, store) -> path("/$storeEngine") { templateEngines.forEach { (templateEngineId, templateEngine) -> - get("/${templateEngineId}/fortunes") { listFortunes(store, templateEngineId, templateEngine) } + val templateUrl = templates.require(templateEngineId) + get("/${templateEngineId}/fortunes") { listFortunes(store, templateUrl, templateEngine) } } get("/db") { dbQuery(store) } @@ -68,13 +69,13 @@ class Controller( } private fun HttpServerContext.listFortunes( - store: BenchmarkStore, templateKind: String, templateAdapter: TemplatePort + store: BenchmarkStore, templateUrl: URL, templateAdapter: TemplatePort ): HttpServerContext { val fortunes = store.findAllFortunes() + Fortune(0, "Additional fortune added at request time.") val sortedFortunes = fortunes.sortedBy { it.message } val context = mapOf("fortunes" to sortedFortunes) - val body = templateAdapter.render(templates.require(templateKind), context) + val body = templateAdapter.render(templateUrl, context) return ok(body, contentType = html) } diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt index 3a724dd900e..ccab68ddc10 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt @@ -24,8 +24,26 @@ internal class BenchmarkSqlStore(engine: String, private val settings: Settings val dbHost = Jvm.systemSettingOrNull("${engine.uppercase()}_DB_HOST") ?: "localhost" val environment = Jvm.systemSettingOrNull(String::class, "BENCHMARK_ENV")?.lowercase() val poolSize = 8 + if (environment == "citrine") Jvm.cpuCount else Jvm.cpuCount * 2 + val postgresqlSettings = listOf( + "useSSL=false", + "jdbcCompliantTruncation=false", + "elideSetAutoCommits=true", + "useLocalSessionState=true", + "cachePrepStmts=true", + "cacheCallableStmts=true", + "alwaysSendSetIsolation=false", + "prepStmtCacheSize=4096", + "cacheServerConfiguration=true", + "prepStmtCacheSqlLimit=2048", + "traceProtocol=false", + "useUnbufferedInput=false", + "useReadAheadInput=false", + "maintainTimeStats=false", + "useServerPrepStmts=true", + "cacheRSMetadata=true" + ).joinToString("&") val config = HikariConfig().apply { - jdbcUrl = "jdbc:postgresql://$dbHost/${settings.databaseName}" + jdbcUrl = "jdbc:postgresql://$dbHost/${settings.databaseName}?$postgresqlSettings" maximumPoolSize = Jvm.systemSettingOrNull(Int::class, "maximumPoolSize") ?: poolSize driverClassName = settings.databaseDriver username = settings.databaseUsername From d687db0db69a1d2253cb6c517ce21c2db852f097 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 4 May 2022 08:50:21 +0200 Subject: [PATCH 033/149] Update Hexagon version --- frameworks/Kotlin/hexagon/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index a247ae755d1..04323e8be2e 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -4,7 +4,7 @@ plugins { } ext { - hexagonVersion = "2.0.7" + hexagonVersion = "2.0.8" hikariVersion = "5.0.1" jettyVersion = "11.0.9" postgresqlVersion = "42.3.4" From 0875de00638050d7f171275356da72d3fe15ca02 Mon Sep 17 00:00:00 2001 From: Juanjo Aguililla Date: Wed, 4 May 2022 09:10:32 +0200 Subject: [PATCH 034/149] Update Hexagon version --- frameworks/Kotlin/hexagon/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index a247ae755d1..04323e8be2e 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -4,7 +4,7 @@ plugins { } ext { - hexagonVersion = "2.0.7" + hexagonVersion = "2.0.8" hikariVersion = "5.0.1" jettyVersion = "11.0.9" postgresqlVersion = "42.3.4" From d7a1c14f8172c3174a80c785dad18e99c7f7bea8 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sat, 7 May 2022 13:28:10 +0200 Subject: [PATCH 035/149] Update DB settings --- frameworks/Kotlin/hexagon/build.gradle | 2 +- .../main/kotlin/store/BenchmarkSqlStore.kt | 21 +++++-------------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 04323e8be2e..45fcb70ef33 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -7,7 +7,7 @@ ext { hexagonVersion = "2.0.8" hikariVersion = "5.0.1" jettyVersion = "11.0.9" - postgresqlVersion = "42.3.4" + postgresqlVersion = "42.3.5" cache2kVersion = "2.6.1.Final" nettyVersion = "4.1.76.Final" diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt index ccab68ddc10..a7b58ac2d84 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt @@ -25,22 +25,11 @@ internal class BenchmarkSqlStore(engine: String, private val settings: Settings val environment = Jvm.systemSettingOrNull(String::class, "BENCHMARK_ENV")?.lowercase() val poolSize = 8 + if (environment == "citrine") Jvm.cpuCount else Jvm.cpuCount * 2 val postgresqlSettings = listOf( - "useSSL=false", - "jdbcCompliantTruncation=false", - "elideSetAutoCommits=true", - "useLocalSessionState=true", - "cachePrepStmts=true", - "cacheCallableStmts=true", - "alwaysSendSetIsolation=false", - "prepStmtCacheSize=4096", - "cacheServerConfiguration=true", - "prepStmtCacheSqlLimit=2048", - "traceProtocol=false", - "useUnbufferedInput=false", - "useReadAheadInput=false", - "maintainTimeStats=false", - "useServerPrepStmts=true", - "cacheRSMetadata=true" + "ssl=false", + "assumeMinServerVersion=12.10", + "databaseMetadataCacheFieldsMiB=8", + "prepareThreshold=1", + "reWriteBatchedInserts=true", ).joinToString("&") val config = HikariConfig().apply { jdbcUrl = "jdbc:postgresql://$dbHost/${settings.databaseName}?$postgresqlSettings" From 33e5726bdf66bcfd85ff7617ff4474994cbc45d9 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Tue, 7 Jun 2022 23:01:52 +0200 Subject: [PATCH 036/149] Use a single store and template engine to simplify benchmark --- frameworks/Kotlin/hexagon/README.md | 36 ++++++++--------- .../Kotlin/hexagon/benchmark_config.json | 40 +++++++++---------- frameworks/Kotlin/hexagon/build.gradle | 7 ++-- frameworks/Kotlin/hexagon/config.toml | 40 +++++++++---------- .../hexagon/src/main/kotlin/Benchmark.kt | 12 +----- .../hexagon/src/main/kotlin/Controller.kt | 40 +++++++------------ .../src/main/kotlin/WebListenerServer.kt | 10 +++-- .../main/kotlin/store/BenchmarkSqlStore.kt | 4 +- 8 files changed, 83 insertions(+), 106 deletions(-) diff --git a/frameworks/Kotlin/hexagon/README.md b/frameworks/Kotlin/hexagon/README.md index 779811d7c31..11e0c78336e 100644 --- a/frameworks/Kotlin/hexagon/README.md +++ b/frameworks/Kotlin/hexagon/README.md @@ -18,42 +18,38 @@ To run the full benchmarks locally, on the project root (not this directory) exe ## Test URLs -In URLs replace `${DB_ENGINE}` with: `postgresql` - -and `${TEMPLATE_ENGINE}` with: `pebble` - ### Jetty * JSON Encoding Test: http://localhost:9090/json * Plain Text Test: http://localhost:9090/plaintext -* Data-Store/Database Mapping Test: http://localhost:9090/${DB_ENGINE}/db?queries=5 -* Fortunes: http://localhost:9090/${DB_ENGINE}/${TEMPLATE_ENGINE}/fortunes -* Database updates: http://localhost:9090/${DB_ENGINE}/update -* Database queries: http://localhost:9090/${DB_ENGINE}/query +* Data-Store/Database Mapping Test: http://localhost:9090/db?queries=5 +* Fortunes: http://localhost:9090/fortunes +* Database updates: http://localhost:9090/update +* Database queries: http://localhost:9090/query ### Netty * JSON Encoding Test: http://localhost:9090/json * Plain Text Test: http://localhost:9090/plaintext -* Data-Store/Database Mapping Test: http://localhost:9090/${DB_ENGINE}/db?queries=5 -* Fortunes: http://localhost:9090/${DB_ENGINE}/${TEMPLATE_ENGINE}/fortunes -* Database updates: http://localhost:9090/${DB_ENGINE}/update -* Database queries: http://localhost:9090/${DB_ENGINE}/query +* Data-Store/Database Mapping Test: http://localhost:9090/db?queries=5 +* Fortunes: http://localhost:9090/fortunes +* Database updates: http://localhost:9090/update +* Database queries: http://localhost:9090/query ### Netty Epoll * JSON Encoding Test: http://localhost:9090/json * Plain Text Test: http://localhost:9090/plaintext -* Data-Store/Database Mapping Test: http://localhost:9090/${DB_ENGINE}/db?queries=5 -* Fortunes: http://localhost:9090/${DB_ENGINE}/${TEMPLATE_ENGINE}/fortunes -* Database updates: http://localhost:9090/${DB_ENGINE}/update -* Database queries: http://localhost:9090/${DB_ENGINE}/query +* Data-Store/Database Mapping Test: http://localhost:9090/db?queries=5 +* Fortunes: http://localhost:9090/fortunes +* Database updates: http://localhost:9090/update +* Database queries: http://localhost:9090/query ### Tomcat * JSON Encoding Test: http://localhost:8080/json * Plain Text Test: http://localhost:8080/plaintext -* Data-Store/Database Mapping Test: http://localhost:8080/${DB_ENGINE}/db?queries=5 -* Fortunes: http://localhost:8080/${DB_ENGINE}/${TEMPLATE_ENGINE}/fortunes -* Database updates: http://localhost:8080/${DB_ENGINE}/update -* Database queries: http://localhost:8080/${DB_ENGINE}/query +* Data-Store/Database Mapping Test: http://localhost:8080/db?queries=5 +* Fortunes: http://localhost:8080/fortunes +* Database updates: http://localhost:8080/update +* Database queries: http://localhost:8080/query diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index aa47cabbe96..fd4254a3355 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -4,11 +4,11 @@ { "default": { "json_url": "/json", - "db_url": "/postgresql/db", - "query_url": "/postgresql/query?queries=", - "fortune_url": "/postgresql/pebble/fortunes", - "update_url": "/postgresql/update?queries=", - "cached_query_url": "/postgresql/cached?count=", + "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", @@ -27,11 +27,11 @@ }, "netty": { "json_url": "/json", - "db_url": "/postgresql/db", - "query_url": "/postgresql/query?queries=", - "fortune_url": "/postgresql/pebble/fortunes", - "update_url": "/postgresql/update?queries=", - "cached_query_url": "/postgresql/cached?count=", + "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", @@ -50,11 +50,11 @@ }, "nettyepoll": { "json_url": "/json", - "db_url": "/postgresql/db", - "query_url": "/postgresql/query?queries=", - "fortune_url": "/postgresql/pebble/fortunes", - "update_url": "/postgresql/update?queries=", - "cached_query_url": "/postgresql/cached?count=", + "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", @@ -73,11 +73,11 @@ }, "tomcat": { "json_url": "/json", - "db_url": "/postgresql/db", - "query_url": "/postgresql/query?queries=", - "fortune_url": "/postgresql/pebble/fortunes", - "update_url": "/postgresql/update?queries=", - "cached_query_url": "/postgresql/cached?count=", + "db_url": "/db", + "query_url": "/query?queries=", + "fortune_url": "/fortunes", + "update_url": "/update?queries=", + "cached_query_url": "/cached-queries?count=", "plaintext_url": "/plaintext", "port": 8080, "approach": "Realistic", diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 45fcb70ef33..e0eb8da23d1 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -4,12 +4,12 @@ plugins { } ext { - hexagonVersion = "2.0.8" + hexagonVersion = "2.0.10" hikariVersion = "5.0.1" jettyVersion = "11.0.9" - postgresqlVersion = "42.3.5" + postgresqlVersion = "42.3.6" cache2kVersion = "2.6.1.Final" - nettyVersion = "4.1.76.Final" + nettyVersion = "4.1.77.Final" gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/$hexagonVersion/gradle" } @@ -32,7 +32,6 @@ war { installDist.dependsOn("war") dependencies { - implementation("com.hexagonkt:http_server_netty:$hexagonVersion") implementation("com.hexagonkt:http_server_netty_epoll:$hexagonVersion") implementation("com.hexagonkt:http_server_jetty:$hexagonVersion") implementation("com.hexagonkt:templates_pebble:$hexagonVersion") diff --git a/frameworks/Kotlin/hexagon/config.toml b/frameworks/Kotlin/hexagon/config.toml index edc7c2cf9aa..ad228b9203e 100644 --- a/frameworks/Kotlin/hexagon/config.toml +++ b/frameworks/Kotlin/hexagon/config.toml @@ -4,11 +4,11 @@ name = "hexagon" [main] urls.plaintext = "/plaintext" urls.json = "/json" -urls.db = "/postgresql/db" -urls.query = "/postgresql/query?queries=" -urls.update = "/postgresql/update?queries=" -urls.fortune = "/postgresql/pebble/fortunes" -urls.cached_query = "/postgresql/cached?count=" +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" @@ -22,11 +22,11 @@ versus = "servlet" [netty] urls.plaintext = "/plaintext" urls.json = "/json" -urls.db = "/postgresql/db" -urls.query = "/postgresql/query?queries=" -urls.update = "/postgresql/update?queries=" -urls.fortune = "/postgresql/pebble/fortunes" -urls.cached_query = "/postgresql/cached?count=" +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" @@ -40,11 +40,11 @@ versus = "netty" [nettyepoll] urls.plaintext = "/plaintext" urls.json = "/json" -urls.db = "/postgresql/db" -urls.query = "/postgresql/query?queries=" -urls.update = "/postgresql/update?queries=" -urls.fortune = "/postgresql/pebble/fortunes" -urls.cached_query = "/postgresql/cached?count=" +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" @@ -58,11 +58,11 @@ versus = "netty" [tomcat] urls.plaintext = "/plaintext" urls.json = "/json" -urls.db = "/postgresql/db" -urls.query = "/postgresql/query?queries=" -urls.update = "/postgresql/update?queries=" -urls.fortune = "/postgresql/pebble/fortunes" -urls.cached_query = "/postgresql/cached?count=" +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" diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt index e86e894e1ec..310bbb81c0a 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt @@ -7,21 +7,11 @@ 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.BenchmarkSqlStore -import com.hexagonkt.store.BenchmarkStore -import com.hexagonkt.templates.TemplatePort import com.hexagonkt.templates.pebble.PebbleAdapter import java.net.InetAddress internal val settings = Settings() -internal val stores: Map by lazy { - mapOf("postgresql" to BenchmarkSqlStore("postgresql")) -} - -internal val templateEngines: Map by lazy { - mapOf("pebble" to PebbleAdapter) -} - private val engines: Map by lazy { mapOf( "jetty" to JettyServletAdapter( @@ -36,7 +26,7 @@ private val engines: Map by lazy { private val server: HttpServer by lazy { val engine = engines[settings.webEngine] ?: error("Unsupported server engine") - val controller = Controller(settings, stores, templateEngines) + val controller = Controller(settings, BenchmarkSqlStore("postgresql"), PebbleAdapter) val serverSettings = HttpServerSettings( bindAddress = InetAddress.getByName(settings.bindAddress), bindPort = settings.bindPort, diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt index 199e8588f75..2c82ad706b8 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt @@ -1,11 +1,11 @@ package com.hexagonkt -import com.hexagonkt.core.require import com.hexagonkt.core.media.ApplicationMedia.JSON import com.hexagonkt.core.media.TextMedia.HTML import com.hexagonkt.core.media.TextMedia.PLAIN -import com.hexagonkt.core.multiMapOf import com.hexagonkt.http.model.ContentType +import com.hexagonkt.http.model.Header +import com.hexagonkt.http.model.HttpFields import com.hexagonkt.http.server.handlers.HttpServerContext import com.hexagonkt.http.server.handlers.PathHandler import com.hexagonkt.http.server.handlers.path @@ -23,8 +23,8 @@ import kotlin.text.Charsets.UTF_8 class Controller( settings: Settings, - stores: Map, - templateEngines: Map, + store: BenchmarkStore, + templateEngine: TemplatePort, ) { private val queriesParam: String = settings.queriesParam private val cachedQueriesParam: String = settings.cachedQueriesParam @@ -34,37 +34,25 @@ class Controller( private val json: ContentType = ContentType(JSON) private val html: ContentType = ContentType(HTML, charset = UTF_8) - private val templates: Map = mapOf( - "pebble" to URL("classpath:fortunes.pebble.html") + private val templateUrl: URL = URL("classpath:fortunes.pebble.html") + + private val headers = HttpFields( + Header("server", "Hexagon"), ) internal val path: PathHandler by lazy { path { on("*") { - val headers = multiMapOf( - "server" to "Hexagon", - "date" to now().toHttpFormat(), - ) - - send(headers = headers) + send(headers = headers + Header("date", now().toHttpFormat())) } get("/plaintext") { ok(settings.textMessage, contentType = plain) } get("/json") { ok(Message(settings.textMessage).serialize(Json.raw), contentType = json) } - - stores.forEach { (storeEngine, store) -> - path("/$storeEngine") { - templateEngines.forEach { (templateEngineId, templateEngine) -> - val templateUrl = templates.require(templateEngineId) - get("/${templateEngineId}/fortunes") { listFortunes(store, templateUrl, templateEngine) } - } - - get("/db") { dbQuery(store) } - get("/query") { getWorlds(store) } - get("/cached") { getCachedWorlds(store) } - get("/update") { updateWorlds(store) } - } - } + get("/fortunes") { listFortunes(store, templateUrl, templateEngine) } + get("/db") { dbQuery(store) } + get("/query") { getWorlds(store) } + get("/cached-queries") { getCachedWorlds(store) } + get("/update") { updateWorlds(store) } } } diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt index eec6f2571d3..d269138faec 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt @@ -1,20 +1,24 @@ package com.hexagonkt -import com.hexagonkt.core.multiMapOf +import com.hexagonkt.http.model.Header +import com.hexagonkt.http.model.HttpFields import com.hexagonkt.http.server.handlers.HttpHandler import com.hexagonkt.http.server.handlers.OnHandler import com.hexagonkt.http.server.servlet.ServletServer +import com.hexagonkt.store.BenchmarkSqlStore +import com.hexagonkt.templates.pebble.PebbleAdapter import jakarta.servlet.annotation.WebListener @WebListener class WebListenerServer(settings: Settings = Settings()) : ServletServer(createHandlers(settings)) { private companion object { + val headers = HttpFields(Header("server", "Tomcat")) fun createHandlers(settings: Settings): List { - val controller = Controller(settings, stores, templateEngines) + val controller = Controller(settings, BenchmarkSqlStore("postgresql"), PebbleAdapter) val controllerPath = controller.path val serverHeaderHandler = OnHandler("*") { - send(headers = multiMapOf("server" to "Tomcat")) + send(headers = headers) } return listOf(serverHeaderHandler, controllerPath) diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt index a7b58ac2d84..f2d68d7cb6c 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt @@ -42,12 +42,12 @@ internal class BenchmarkSqlStore(engine: String, private val settings: Settings } override fun findAllFortunes(): List { - val fortunes = mutableListOf() + var fortunes = listOf() dataSource.connection.use { con: Connection -> val rs = con.prepareStatement(SELECT_ALL_FORTUNES).executeQuery() while (rs.next()) - fortunes += Fortune(rs.getInt(1), rs.getString(2)) + fortunes = fortunes + Fortune(rs.getInt(1), rs.getString(2)) } return fortunes From fb135f1ab283caaab91c742cd7dd114fb3077f9c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Jun 2022 06:32:27 +0000 Subject: [PATCH 037/149] 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] --- frameworks/Java/wicket/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Java/wicket/pom.xml b/frameworks/Java/wicket/pom.xml index 8c8473d6ab0..ec30df52f27 100644 --- a/frameworks/Java/wicket/pom.xml +++ b/frameworks/Java/wicket/pom.xml @@ -64,7 +64,7 @@ mysql mysql-connector-java - 8.0.27 + 8.0.28 From 1192a06038bf88da2fc4c8e41a65e33734836a0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jun 2022 17:27:10 +0000 Subject: [PATCH 038/149] 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] --- frameworks/Java/javalin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Java/javalin/pom.xml b/frameworks/Java/javalin/pom.xml index 98e5d550d4c..a3ff499ca84 100644 --- a/frameworks/Java/javalin/pom.xml +++ b/frameworks/Java/javalin/pom.xml @@ -16,7 +16,7 @@ 2.12.6.1 4.0.2 42.3.3 - 4.2.0 + 4.2.1 3.1.5 From 310167b127eb1d7d31bc1543fa28ea24ec210c1c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Jul 2022 22:32:15 +0000 Subject: [PATCH 039/149] 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] --- frameworks/Python/starlette/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Python/starlette/requirements.txt b/frameworks/Python/starlette/requirements.txt index 5d52022437d..a9d791c7b47 100644 --- a/frameworks/Python/starlette/requirements.txt +++ b/frameworks/Python/starlette/requirements.txt @@ -2,6 +2,6 @@ asyncpg==0.25.0 gunicorn==20.1.0 Jinja2==3.1.2 starlette==0.19.1 -ujson==5.2.0 +ujson==5.4.0 uvicorn==0.17.6 uvloop==0.16.0 From 37e0005e273f2d1cb607a564da4d9943e3e98da3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Jul 2022 22:40:09 +0000 Subject: [PATCH 040/149] 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] --- frameworks/Python/django/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Python/django/requirements.txt b/frameworks/Python/django/requirements.txt index e9c9255cbcb..0c8cdd97725 100644 --- a/frameworks/Python/django/requirements.txt +++ b/frameworks/Python/django/requirements.txt @@ -5,4 +5,4 @@ meinheld==1.0.2 mysqlclient==1.4.6 psycopg2==2.8.6 pytz==2020.4 -ujson==5.2.0 \ No newline at end of file +ujson==5.4.0 \ No newline at end of file From 9d1378cde62f3a87fe810e5e10c7ef212a69cfe3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Jul 2022 22:40:11 +0000 Subject: [PATCH 041/149] 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] --- frameworks/Python/routerling/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Python/routerling/requirements.txt b/frameworks/Python/routerling/requirements.txt index 9080a3c642b..7b68e45f102 100644 --- a/frameworks/Python/routerling/requirements.txt +++ b/frameworks/Python/routerling/requirements.txt @@ -6,6 +6,6 @@ h11==0.12.0 Jinja2==3.0.1 MarkupSafe==2.0.1 routerling==0.3.1 -ujson==5.2.0 +ujson==5.4.0 uvloop==0.16.0 uvicorn==0.14.0 From e0bb50bc632dd80144d0a50c6ab1444119e21151 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Jul 2022 22:44:16 +0000 Subject: [PATCH 042/149] 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] --- frameworks/Python/japronto/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Python/japronto/requirements.txt b/frameworks/Python/japronto/requirements.txt index 2990ff079ea..a28213a7c90 100644 --- a/frameworks/Python/japronto/requirements.txt +++ b/frameworks/Python/japronto/requirements.txt @@ -1,2 +1,2 @@ git+https://github.com/squeaky-pl/japronto.git#egg=japronto -ujson==5.2.0 +ujson==5.4.0 From 5299732a41c300aa60f40aa502e3a70d11fbb29b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Jul 2022 22:45:58 +0000 Subject: [PATCH 043/149] 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] --- frameworks/Python/fastapi/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Python/fastapi/requirements.txt b/frameworks/Python/fastapi/requirements.txt index e53fe307dd3..dc928416e92 100644 --- a/frameworks/Python/fastapi/requirements.txt +++ b/frameworks/Python/fastapi/requirements.txt @@ -2,7 +2,7 @@ asyncpg==0.21.0 gunicorn==20.0.4 Jinja2==2.11.3 markupsafe==2.0.1 -ujson==5.2.0 +ujson==5.4.0 uvloop==0.14.0 uvicorn==0.11.3 fastapi==0.65.2 From 8dffc32f73cbad2c3d5a7e1a2bf4bbf50cf885de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Jul 2022 22:47:15 +0000 Subject: [PATCH 044/149] 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] --- frameworks/Python/uvicorn/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Python/uvicorn/requirements.txt b/frameworks/Python/uvicorn/requirements.txt index 5eabe2676f4..e2bb7f3304a 100644 --- a/frameworks/Python/uvicorn/requirements.txt +++ b/frameworks/Python/uvicorn/requirements.txt @@ -1,6 +1,6 @@ asyncpg==0.21.0 gunicorn==20.0.4 Jinja2==3.0.3 -ujson==5.2.0 +ujson==5.4.0 uvloop==0.14.0 uvicorn==0.11.7 From cf9a280f5a762ccfe7027da718b88c69d6f82e0a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Jul 2022 22:52:09 +0000 Subject: [PATCH 045/149] 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] --- frameworks/Python/flask/requirements-pypy.txt | 2 +- frameworks/Python/flask/requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frameworks/Python/flask/requirements-pypy.txt b/frameworks/Python/flask/requirements-pypy.txt index 756f6e93297..132102fdc92 100644 --- a/frameworks/Python/flask/requirements-pypy.txt +++ b/frameworks/Python/flask/requirements-pypy.txt @@ -11,4 +11,4 @@ MarkupSafe==2.0.1 meinheld==1.0.2 uWSGI==2.0.19.1 Werkzeug==2.0.1 -ujson==5.2.0 \ No newline at end of file +ujson==5.4.0 \ No newline at end of file diff --git a/frameworks/Python/flask/requirements.txt b/frameworks/Python/flask/requirements.txt index 744b623e065..89d3bb2e297 100644 --- a/frameworks/Python/flask/requirements.txt +++ b/frameworks/Python/flask/requirements.txt @@ -12,5 +12,5 @@ MarkupSafe==2.0.1 meinheld==1.0.2 uWSGI==2.0.19.1 Werkzeug==2.0.1 -ujson==5.2.0 +ujson==5.4.0 orjson==3.6.0 From a4fe6ec04baa58a1c9264c4ec58310cb4fc98996 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Jul 2022 22:57:17 +0000 Subject: [PATCH 046/149] 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] --- frameworks/Python/aiohttp/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Python/aiohttp/requirements.txt b/frameworks/Python/aiohttp/requirements.txt index b11893aec72..aea8aff7754 100644 --- a/frameworks/Python/aiohttp/requirements.txt +++ b/frameworks/Python/aiohttp/requirements.txt @@ -5,5 +5,5 @@ gunicorn==20.1 jinja2==3.0.3 psycopg2==2.9.2 SQLAlchemy==1.4.29 -ujson==5.1 +ujson==5.4.0 uvloop==0.16 From 31887ce0e5e9e7ef1dc69f4f7f60ea588e84c9e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Jul 2022 11:43:52 +0000 Subject: [PATCH 047/149] 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] --- frameworks/Ruby/rails/Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frameworks/Ruby/rails/Gemfile.lock b/frameworks/Ruby/rails/Gemfile.lock index 819c83670c6..dfc9e4fd60e 100644 --- a/frameworks/Ruby/rails/Gemfile.lock +++ b/frameworks/Ruby/rails/Gemfile.lock @@ -80,7 +80,7 @@ GEM listen (3.7.1) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - loofah (2.13.0) + loofah (2.18.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) @@ -139,7 +139,7 @@ GEM rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) - rails-html-sanitizer (1.4.2) + rails-html-sanitizer (1.4.3) loofah (~> 2.3) railties (7.0.1) actionpack (= 7.0.1) From 8534e0eb2c8b8d6b69be037dd686715ee23e41ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Jul 2022 22:15:33 +0000 Subject: [PATCH 048/149] 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] --- frameworks/Java/jetty/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Java/jetty/pom.xml b/frameworks/Java/jetty/pom.xml index c860b1d4bf4..79112565a05 100644 --- a/frameworks/Java/jetty/pom.xml +++ b/frameworks/Java/jetty/pom.xml @@ -11,7 +11,7 @@ UTF-8 11 11 - 9.4.41.v20210516 + 10.0.10 hello.handler.HelloWebServer From 32f13be742dd857ad7e96e9c758b25c41e879359 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Jul 2022 21:34:24 +0000 Subject: [PATCH 049/149] 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] --- frameworks/Java/undertow/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Java/undertow/pom.xml b/frameworks/Java/undertow/pom.xml index 61f2251bff3..6d766169f9c 100644 --- a/frameworks/Java/undertow/pom.xml +++ b/frameworks/Java/undertow/pom.xml @@ -19,7 +19,7 @@ 3.2.1 0.9.6 42.3.3 - 2.2.11.Final + 2.2.15.Final From fc3dfc1c41713e1671015fd4c59401bc84c9ff1d Mon Sep 17 00:00:00 2001 From: jaguililla Date: Tue, 19 Jul 2022 18:49:14 +0200 Subject: [PATCH 050/149] Update versions --- frameworks/Kotlin/hexagon/build.gradle | 10 +++++----- frameworks/Kotlin/hexagon/hexagon-netty.dockerfile | 2 +- .../Kotlin/hexagon/hexagon-nettyepoll.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile | 4 ++-- frameworks/Kotlin/hexagon/hexagon.dockerfile | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index e0eb8da23d1..8ee07ba3ca1 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,15 +1,15 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "1.6.21" + id "org.jetbrains.kotlin.jvm" version "1.7.10" } ext { - hexagonVersion = "2.0.10" + hexagonVersion = "2.0.17" hikariVersion = "5.0.1" - jettyVersion = "11.0.9" - postgresqlVersion = "42.3.6" + jettyVersion = "11.0.11" + postgresqlVersion = "42.4.0" cache2kVersion = "2.6.1.Final" - nettyVersion = "4.1.77.Final" + nettyVersion = "4.1.79.Final" gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/$hexagonVersion/gradle" } diff --git a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile index 3480f54996e..579a9402136 100644 --- a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.4.2-jdk11 AS gradle_build +FROM gradle:7.5.0-jdk17-alpine AS gradle_build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile index e97878b9e9e..e9caab6bc32 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.4.2-jdk11 AS gradle_build +FROM gradle:7.5.0-jdk17-alpine AS gradle_build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index 682ca865413..5134fedad4c 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.4.2-jdk11 AS gradle_build +FROM gradle:7.5.0-jdk17-alpine AS gradle_build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN gradle --quiet # # RUNTIME # -FROM tomcat:10.0.14-jre17-temurin +FROM tomcat:10.1.0-jre17-temurin ENV DBSTORE postgresql ENV POSTGRESQL_DB_HOST tfb-database ENV DISABLE_CHECKS true diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index 8742932ca3b..465f2d82146 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.4.2-jdk11 AS gradle_build +FROM gradle:7.5.0-jdk17-alpine AS gradle_build USER root WORKDIR /hexagon From d7715ab8c0886e4f858b230f81f49972671be6ef Mon Sep 17 00:00:00 2001 From: Juanjo Aguililla Date: Wed, 20 Jul 2022 10:56:28 +0200 Subject: [PATCH 051/149] Update README.md --- frameworks/Kotlin/hexagon/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/README.md b/frameworks/Kotlin/hexagon/README.md index 11e0c78336e..28397711a58 100644 --- a/frameworks/Kotlin/hexagon/README.md +++ b/frameworks/Kotlin/hexagon/README.md @@ -2,7 +2,7 @@ # Hexagon Benchmarking Test This is the Hexagon portion of a [benchmarking test suite](../../../README.md) comparing a variety -of web development platforms. The test utilizes Hexagon routes, serialization and database access. +of web development platforms. The test utilizes Hexagon routes and serialization. ## Tests From a1db1c88c79fc93c64f7e5f33b355df0748f73bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Aug 2022 05:21:44 +0000 Subject: [PATCH 052/149] 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] --- frameworks/Python/sanic/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Python/sanic/requirements.txt b/frameworks/Python/sanic/requirements.txt index 13b48a818a3..36f8d2c8246 100644 --- a/frameworks/Python/sanic/requirements.txt +++ b/frameworks/Python/sanic/requirements.txt @@ -1,4 +1,4 @@ asyncpg==0.25.0 Jinja2==3.1.2 -sanic==22.3.1 +sanic==22.6.1 uvloop==0.16.0 From 6325b02dcb6fb9188f6f9406319bcc05e3c97ca3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Aug 2022 05:56:24 +0000 Subject: [PATCH 053/149] 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] --- frameworks/Java/light-java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Java/light-java/pom.xml b/frameworks/Java/light-java/pom.xml index 14cf18d003c..ebe3634dc9d 100644 --- a/frameworks/Java/light-java/pom.xml +++ b/frameworks/Java/light-java/pom.xml @@ -28,7 +28,7 @@ 2.2.15.Final 3.3.1 8.0.28 - 42.3.3 + 42.4.1 1.8.4 0.9.6 3.8.0 From 382854885dc78c7aa2a1a68ddbcd57fc64a59853 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Aug 2022 05:56:24 +0000 Subject: [PATCH 054/149] 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] --- frameworks/Java/rapidoid/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Java/rapidoid/pom.xml b/frameworks/Java/rapidoid/pom.xml index 57b2e1c9c6b..eed7ef401d9 100644 --- a/frameworks/Java/rapidoid/pom.xml +++ b/frameworks/Java/rapidoid/pom.xml @@ -28,7 +28,7 @@ org.postgresql postgresql - 42.3.3 + 42.4.1 com.zaxxer From 7c3305d41807547cdb3c9dbcf1a351eb37b8395a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Aug 2022 05:56:24 +0000 Subject: [PATCH 055/149] 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] --- frameworks/Java/jooby/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Java/jooby/pom.xml b/frameworks/Java/jooby/pom.xml index efb0b9d81c9..8839413f957 100644 --- a/frameworks/Java/jooby/pom.xml +++ b/frameworks/Java/jooby/pom.xml @@ -14,7 +14,7 @@ 2.9.5 4.1.77.Final 1.9.5 - 42.3.3 + 42.4.1 UTF-8 11 11 From f0d8e988577bcfceab0797cabbc64417cd33da06 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Aug 2022 05:56:24 +0000 Subject: [PATCH 056/149] 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] --- frameworks/Java/servlet/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Java/servlet/pom.xml b/frameworks/Java/servlet/pom.xml index 631fb2788b5..fd63f64978f 100644 --- a/frameworks/Java/servlet/pom.xml +++ b/frameworks/Java/servlet/pom.xml @@ -108,7 +108,7 @@ org.postgresql postgresql - 42.3.3 + 42.4.1 From 70aebd078421c6bb86db9d806484ab56be9c899d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Aug 2022 05:56:25 +0000 Subject: [PATCH 057/149] 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] --- frameworks/Java/spring-webflux/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Java/spring-webflux/pom.xml b/frameworks/Java/spring-webflux/pom.xml index e0e17a2cdef..43b7bedcaef 100644 --- a/frameworks/Java/spring-webflux/pom.xml +++ b/frameworks/Java/spring-webflux/pom.xml @@ -21,7 +21,7 @@ 11 UTF-8 1.0.0.M2 - 42.3.3 + 42.4.1 0.11.4 0.2.4 1.0.0.M7 From 9bddbe971e80e5ea2d976b5dc6484b45170c75cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Aug 2022 05:56:25 +0000 Subject: [PATCH 058/149] 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] --- frameworks/Java/smart-socket/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Java/smart-socket/pom.xml b/frameworks/Java/smart-socket/pom.xml index 9bd1b1f1af3..1c48ccf3ea4 100644 --- a/frameworks/Java/smart-socket/pom.xml +++ b/frameworks/Java/smart-socket/pom.xml @@ -56,7 +56,7 @@ org.postgresql postgresql - 42.3.3 + 42.4.1 From 58b628d75de475b623cc1a53d1b37288505e63e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Aug 2022 05:56:25 +0000 Subject: [PATCH 059/149] 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] --- frameworks/Java/act/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Java/act/pom.xml b/frameworks/Java/act/pom.xml index a27f7409769..c65ea1dfce7 100644 --- a/frameworks/Java/act/pom.xml +++ b/frameworks/Java/act/pom.xml @@ -70,7 +70,7 @@ 1.8 5.1.47 - 42.3.3 + 42.4.1 1.3.2 3.4 com.techempower.act.AppEntry From 1f8d756e10dc72057d0af9541e204624e47a6594 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Aug 2022 05:56:27 +0000 Subject: [PATCH 060/149] 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] --- frameworks/Kotlin/kooby/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/kooby/pom.xml b/frameworks/Kotlin/kooby/pom.xml index 51160f7f72a..0dfc7bc9f84 100644 --- a/frameworks/Kotlin/kooby/pom.xml +++ b/frameworks/Kotlin/kooby/pom.xml @@ -13,7 +13,7 @@ 2.9.5 - 42.3.3 + 42.4.1 UTF-8 11 11 From 468cb594cffe85e37cfa65aa94b8576600ed5ab2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Aug 2022 05:56:27 +0000 Subject: [PATCH 061/149] 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] --- frameworks/Java/dropwizard/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Java/dropwizard/pom.xml b/frameworks/Java/dropwizard/pom.xml index 8fcbeb3c6b6..319c13f37ff 100644 --- a/frameworks/Java/dropwizard/pom.xml +++ b/frameworks/Java/dropwizard/pom.xml @@ -19,7 +19,7 @@ 2.3.0 8.0.28 2.9.4 - 42.3.3 + 42.4.1 3.8.0 3.1.0 3.1.1 From ee593a29ca8d3c9a8d2850b68daa7fb3100fea02 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Aug 2022 05:59:58 +0000 Subject: [PATCH 062/149] 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] --- frameworks/Java/hserver/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Java/hserver/pom.xml b/frameworks/Java/hserver/pom.xml index 291ff8be9a2..8699552d1ba 100644 --- a/frameworks/Java/hserver/pom.xml +++ b/frameworks/Java/hserver/pom.xml @@ -10,7 +10,7 @@ UTF-8 3.3.1 - 42.3.3 + 42.4.1 2.9.90 From 03ca6af0c9aa1aad7231fe25f7da0f482cb4d766 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Aug 2022 06:07:01 +0000 Subject: [PATCH 063/149] 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] --- frameworks/Java/undertow/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Java/undertow/pom.xml b/frameworks/Java/undertow/pom.xml index f13755d14d7..080c2cf7ae3 100644 --- a/frameworks/Java/undertow/pom.xml +++ b/frameworks/Java/undertow/pom.xml @@ -19,7 +19,7 @@ 3.3.0 3.2.2 0.9.10 - 42.4.0 + 42.4.1 2.2.18.Final From 36ae7377838e58e6202b4b95eca0ac8b51c6043c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Aug 2022 07:04:23 +0000 Subject: [PATCH 064/149] 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] --- frameworks/Kotlin/ktor/ktor/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/ktor/ktor/pom.xml b/frameworks/Kotlin/ktor/ktor/pom.xml index b891cc71479..ab847c5b2c0 100644 --- a/frameworks/Kotlin/ktor/ktor/pom.xml +++ b/frameworks/Kotlin/ktor/ktor/pom.xml @@ -20,7 +20,7 @@ 5.0.0 1.2.4 8.0.28 - 42.2.23 + 42.4.1 From b851884430cda491cebc1251a71f6bad294a223d Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sat, 6 Aug 2022 13:34:08 +0200 Subject: [PATCH 065/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 8ee07ba3ca1..1b41c2be7ce 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -7,7 +7,7 @@ ext { hexagonVersion = "2.0.17" hikariVersion = "5.0.1" jettyVersion = "11.0.11" - postgresqlVersion = "42.4.0" + postgresqlVersion = "42.4.1" cache2kVersion = "2.6.1.Final" nettyVersion = "4.1.79.Final" From 4759c4c0335c1767d59b89b27f0f5dcff2a77646 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Aug 2022 19:09:33 +0000 Subject: [PATCH 066/149] 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] --- frameworks/Java/light-java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Java/light-java/pom.xml b/frameworks/Java/light-java/pom.xml index ebe3634dc9d..499d698332b 100644 --- a/frameworks/Java/light-java/pom.xml +++ b/frameworks/Java/light-java/pom.xml @@ -25,7 +25,7 @@ 11 2.0.1 1.2.3 - 2.2.15.Final + 2.2.19.Final 3.3.1 8.0.28 42.4.1 From be64e352cfd44ca7acd5c5e6664f3ddbae19ab88 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Aug 2022 19:09:43 +0000 Subject: [PATCH 067/149] 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] --- frameworks/Java/undertow/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Java/undertow/pom.xml b/frameworks/Java/undertow/pom.xml index 080c2cf7ae3..7244e5c4253 100644 --- a/frameworks/Java/undertow/pom.xml +++ b/frameworks/Java/undertow/pom.xml @@ -20,7 +20,7 @@ 3.2.2 0.9.10 42.4.1 - 2.2.18.Final + 2.2.19.Final From 05f31bfb8e1a32e5625fe7f95d2071591ded31c5 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 8 Sep 2022 17:11:53 +0200 Subject: [PATCH 068/149] Delete Gradle Wrapper --- .../hexagon/gradle/wrapper/gradle-wrapper.jar | Bin 59821 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - frameworks/Kotlin/hexagon/gradlew | 234 ------------------ frameworks/Kotlin/hexagon/gradlew.bat | 89 ------- 4 files changed, 328 deletions(-) delete mode 100644 frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar delete mode 100644 frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties delete mode 100755 frameworks/Kotlin/hexagon/gradlew delete mode 100644 frameworks/Kotlin/hexagon/gradlew.bat diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 41d9927a4d4fb3f96a785543079b8df6723c946b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59821 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 diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 41dfb87909a..00000000000 --- a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/frameworks/Kotlin/hexagon/gradlew b/frameworks/Kotlin/hexagon/gradlew deleted file mode 100755 index 1b6c787337f..00000000000 --- a/frameworks/Kotlin/hexagon/gradlew +++ /dev/null @@ -1,234 +0,0 @@ -#!/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/master/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 - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# 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*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - 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 \ - "$@" - -# 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" "$@" diff --git a/frameworks/Kotlin/hexagon/gradlew.bat b/frameworks/Kotlin/hexagon/gradlew.bat deleted file mode 100644 index 107acd32c4e..00000000000 --- a/frameworks/Kotlin/hexagon/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@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=. -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%" == "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%"=="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! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega From 189e19de6cc85450cc23fd23237e9cd75899a324 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 8 Sep 2022 22:42:39 +0200 Subject: [PATCH 069/149] Use different JSON serializer --- frameworks/Kotlin/hexagon/build.gradle | 8 +++--- .../hexagon/src/main/kotlin/Controller.kt | 28 +++++++++++++++---- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 1b41c2be7ce..4d3e714d3f4 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -4,12 +4,12 @@ plugins { } ext { - hexagonVersion = "2.0.17" + hexagonVersion = "2.0.22" hikariVersion = "5.0.1" jettyVersion = "11.0.11" - postgresqlVersion = "42.4.1" + postgresqlVersion = "42.5.0" cache2kVersion = "2.6.1.Final" - nettyVersion = "4.1.79.Final" + nettyVersion = "4.1.80.Final" gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/$hexagonVersion/gradle" } @@ -36,7 +36,7 @@ dependencies { implementation("com.hexagonkt:http_server_jetty:$hexagonVersion") implementation("com.hexagonkt:templates_pebble:$hexagonVersion") implementation("com.hexagonkt:logging_slf4j_jul:$hexagonVersion") - implementation("com.hexagonkt:serialization_jackson_json:$hexagonVersion") + implementation("com.hexagonkt:serialization_dsl_json:$hexagonVersion") implementation("io.netty:netty-transport-native-epoll:$nettyVersion:linux-x86_64") implementation("org.cache2k:cache2k-core:$cache2kVersion") diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt index 2c82ad706b8..b805071c521 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt @@ -1,5 +1,6 @@ package com.hexagonkt +import com.hexagonkt.core.fieldsMapOf import com.hexagonkt.core.media.ApplicationMedia.JSON import com.hexagonkt.core.media.TextMedia.HTML import com.hexagonkt.core.media.TextMedia.PLAIN @@ -10,7 +11,7 @@ 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.serialization.jackson.json.Json +import com.hexagonkt.serialization.dsl.json.Json import com.hexagonkt.serialization.serialize import com.hexagonkt.store.BenchmarkStore import com.hexagonkt.templates.TemplatePort @@ -47,7 +48,7 @@ class Controller( } get("/plaintext") { ok(settings.textMessage, contentType = plain) } - get("/json") { ok(Message(settings.textMessage).serialize(Json.raw), contentType = json) } + get("/json") { ok(Message(settings.textMessage).toMap().serialize(Json.raw), contentType = json) } get("/fortunes") { listFortunes(store, templateUrl, templateEngine) } get("/db") { dbQuery(store) } get("/query") { getWorlds(store) } @@ -71,7 +72,7 @@ class Controller( private fun HttpServerContext.dbQuery(store: BenchmarkStore): HttpServerContext { val ids = listOf(randomWorld()) val worlds = store.findWorlds(ids) - val world = worlds.first() + val world = worlds.first().toMap() return sendJson(world) } @@ -79,7 +80,7 @@ class Controller( private fun HttpServerContext.getWorlds(store: BenchmarkStore): HttpServerContext { val worldsCount = getWorldsCount(queriesParam) val ids = (1..worldsCount).map { randomWorld() } - val worlds = store.findWorlds(ids) + val worlds = store.findWorlds(ids).map { it.toMap() } return sendJson(worlds) } @@ -87,7 +88,7 @@ class Controller( private fun HttpServerContext.getCachedWorlds(store: BenchmarkStore): HttpServerContext { val worldsCount = getWorldsCount(cachedQueriesParam) val ids = (1..worldsCount).map { randomWorld() } - val worlds = store.findCachedWorlds(ids) + val worlds = store.findCachedWorlds(ids).map { it.toMap() } return sendJson(worlds) } @@ -98,7 +99,7 @@ class Controller( store.replaceWorlds(worlds) - return sendJson(worlds) + return sendJson(worlds.map { it.toMap() }) } private fun HttpServerContext.sendJson(body: Any): HttpServerContext = @@ -116,4 +117,19 @@ class Controller( private fun randomWorld(): Int = ThreadLocalRandom.current().nextInt(worldRows) + 1 + + private fun Message.toMap(): Map = + fieldsMapOf(Message::message to message) + + private fun World.toMap(): Map = + fieldsMapOf( + World::id to id, + World::randomNumber to randomNumber, + ) + + private fun CachedWorld.toMap(): Map = + fieldsMapOf( + CachedWorld::id to id, + CachedWorld::randomNumber to randomNumber, + ) } From 5e47af8fcd3b54154c169473195e2409c80cd75d Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 8 Sep 2022 22:53:18 +0200 Subject: [PATCH 070/149] Restore non Hexagon files --- frameworks/Java/dropwizard/pom.xml | 2 +- frameworks/Python/sanic/requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frameworks/Java/dropwizard/pom.xml b/frameworks/Java/dropwizard/pom.xml index 319c13f37ff..8fcbeb3c6b6 100644 --- a/frameworks/Java/dropwizard/pom.xml +++ b/frameworks/Java/dropwizard/pom.xml @@ -19,7 +19,7 @@ 2.3.0 8.0.28 2.9.4 - 42.4.1 + 42.3.3 3.8.0 3.1.0 3.1.1 diff --git a/frameworks/Python/sanic/requirements.txt b/frameworks/Python/sanic/requirements.txt index 36f8d2c8246..13b48a818a3 100644 --- a/frameworks/Python/sanic/requirements.txt +++ b/frameworks/Python/sanic/requirements.txt @@ -1,4 +1,4 @@ asyncpg==0.25.0 Jinja2==3.1.2 -sanic==22.6.1 +sanic==22.3.1 uvloop==0.16.0 From 67f6bf1a1794ee0450c3654cd23f7dba733ebdba Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 8 Sep 2022 23:25:40 +0200 Subject: [PATCH 071/149] Update Hexagon version --- frameworks/Kotlin/hexagon/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 4d3e714d3f4..fd9276185c4 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -4,7 +4,7 @@ plugins { } ext { - hexagonVersion = "2.0.22" + hexagonVersion = "2.0.23" hikariVersion = "5.0.1" jettyVersion = "11.0.11" postgresqlVersion = "42.5.0" From c2f187e8661ed5673a0e014a085848118ee9eb56 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 8 Sep 2022 23:45:00 +0200 Subject: [PATCH 072/149] Run pipeline From 61b499fbb3b447c38034566337db100c2ee8ad49 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 9 Sep 2022 08:19:30 +0200 Subject: [PATCH 073/149] Run pipeline From 4422de8915e70cdca67a07c2e0fdb0610757924b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Sep 2022 03:28:55 +0000 Subject: [PATCH 074/149] 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] --- frameworks/Rust/axum/Cargo.lock | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frameworks/Rust/axum/Cargo.lock b/frameworks/Rust/axum/Cargo.lock index f7ced7468a4..dd0590e28d8 100644 --- a/frameworks/Rust/axum/Cargo.lock +++ b/frameworks/Rust/axum/Cargo.lock @@ -123,9 +123,9 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4f44a0e6200e9d11a1cdc989e4b358f6e3d354fbf48478f345a17f4e43f8635" +checksum = "d9f0c0a60006f2a293d82d571f635042a72edf927539b7685bd62d361963839b" dependencies = [ "async-trait", "bytes", @@ -133,6 +133,8 @@ dependencies = [ "http", "http-body", "mime", + "tower-layer", + "tower-service", ] [[package]] From 534bc5f5811e580b680ebd366449df3d2d37deb3 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 15 Sep 2022 11:28:41 +0200 Subject: [PATCH 075/149] Revert "Bump axum-core from 0.2.7 to 0.2.8 in /frameworks/Rust/axum" This reverts commit 4422de8915e70cdca67a07c2e0fdb0610757924b. --- frameworks/Rust/axum/Cargo.lock | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/frameworks/Rust/axum/Cargo.lock b/frameworks/Rust/axum/Cargo.lock index dd0590e28d8..f7ced7468a4 100644 --- a/frameworks/Rust/axum/Cargo.lock +++ b/frameworks/Rust/axum/Cargo.lock @@ -123,9 +123,9 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.2.8" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9f0c0a60006f2a293d82d571f635042a72edf927539b7685bd62d361963839b" +checksum = "e4f44a0e6200e9d11a1cdc989e4b358f6e3d354fbf48478f345a17f4e43f8635" dependencies = [ "async-trait", "bytes", @@ -133,8 +133,6 @@ dependencies = [ "http", "http-body", "mime", - "tower-layer", - "tower-service", ] [[package]] From 9df2ba8c02756000be15e874e6a8151fc6b5ecc1 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Tue, 29 Nov 2022 14:22:23 +0100 Subject: [PATCH 076/149] Version updates, code refactor and new benchmark cases --- .../Kotlin/hexagon/benchmark_config.json | 69 +++++ frameworks/Kotlin/hexagon/build.gradle | 10 +- frameworks/Kotlin/hexagon/config.toml | 54 ++++ .../hexagon/gradle/wrapper/gradle-wrapper.jar | Bin 59536 -> 61574 bytes .../gradle/wrapper/gradle-wrapper.properties | 3 +- frameworks/Kotlin/hexagon/gradlew | 269 +++++++++++------- frameworks/Kotlin/hexagon/gradlew.bat | 15 +- .../hexagon-jettyloom-pgclient.dockerfile | 27 ++ .../hexagon/hexagon-jettyloom.dockerfile | 27 ++ .../Kotlin/hexagon/hexagon-netty.dockerfile | 9 +- .../hexagon-nettyepoll-pgclient.dockerfile | 27 ++ .../hexagon/hexagon-nettyepoll.dockerfile | 9 +- .../Kotlin/hexagon/hexagon-tomcat.dockerfile | 9 +- frameworks/Kotlin/hexagon/hexagon.dockerfile | 9 +- .../hexagon/src/main/kotlin/Benchmark.kt | 20 +- .../hexagon/src/main/kotlin/Controller.kt | 7 +- .../Kotlin/hexagon/src/main/kotlin/Model.kt | 6 - .../hexagon/src/main/kotlin/Settings.kt | 1 + .../src/main/kotlin/WebListenerServer.kt | 6 +- .../src/main/kotlin/model/CachedWorld.kt | 3 + .../hexagon/src/main/kotlin/model/Fortune.kt | 3 + .../hexagon/src/main/kotlin/model/Message.kt | 3 + .../hexagon/src/main/kotlin/model/World.kt | 3 + .../kotlin/store/BenchmarkPgClientStore.kt | 116 ++++++++ .../main/kotlin/store/BenchmarkSqlStore.kt | 21 +- .../src/main/kotlin/store/BenchmarkStore.kt | 6 +- 26 files changed, 574 insertions(+), 158 deletions(-) create mode 100644 frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile create mode 100644 frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile create mode 100644 frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile delete mode 100644 frameworks/Kotlin/hexagon/src/main/kotlin/Model.kt create mode 100644 frameworks/Kotlin/hexagon/src/main/kotlin/model/CachedWorld.kt create mode 100644 frameworks/Kotlin/hexagon/src/main/kotlin/model/Fortune.kt create mode 100644 frameworks/Kotlin/hexagon/src/main/kotlin/model/Message.kt create mode 100644 frameworks/Kotlin/hexagon/src/main/kotlin/model/World.kt create mode 100644 frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkPgClientStore.kt diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index fd4254a3355..2a4022a088b 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/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", diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index fd9276185c4..ad55d00bcfd 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/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" } diff --git a/frameworks/Kotlin/hexagon/config.toml b/frameworks/Kotlin/hexagon/config.toml index ad228b9203e..d51d0e8ccf6 100644 --- a/frameworks/Kotlin/hexagon/config.toml +++ b/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" diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar index 7454180f2ae8848c63b8b4dea2cb829da983f2fa..943f0cbfa754578e88a3dae77fce6e3dea56edbf 100644 GIT binary patch delta 36900 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

yHlr~Qj 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 GTKgBj+ffbx diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties index 05679dc3c18..3f4def4a917 100644 --- a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties +++ b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip +distributionUrl=https://services.gradle.org/distributions/gradle-7.6-bin.zip +networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/frameworks/Kotlin/hexagon/gradlew b/frameworks/Kotlin/hexagon/gradlew index 744e882ed57..65dcd68d65c 100755 --- a/frameworks/Kotlin/hexagon/gradlew +++ b/frameworks/Kotlin/hexagon/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# 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. @@ -17,67 +17,101 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# 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 -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +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 -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +# 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" +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 - ;; +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 @@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 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" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + 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 @@ -106,80 +140,105 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +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 -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -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" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +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 - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + 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 - i=`expr $i + 1` + # 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 - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` +# 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. +# -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/frameworks/Kotlin/hexagon/gradlew.bat b/frameworks/Kotlin/hexagon/gradlew.bat index 107acd32c4e..93e3f59f135 100644 --- a/frameworks/Kotlin/hexagon/gradlew.bat +++ b/frameworks/Kotlin/hexagon/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +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! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +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 diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile new file mode 100644 index 00000000000..18d9d309d13 --- /dev/null +++ b/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 diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile new file mode 100644 index 00000000000..e681fc03572 --- /dev/null +++ b/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 diff --git a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile index 579a9402136..05c93562cf0 100644 --- a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile +++ b/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 diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile new file mode 100644 index 00000000000..efc4db12aaa --- /dev/null +++ b/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 diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile index e9caab6bc32..87260f430e9 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile +++ b/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 diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index 5134fedad4c..d15c7180a93 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/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 diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index 465f2d82146..6edc32dc1dd 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/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 diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt index 310bbb81c0a..a296a9d261d 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt +++ b/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 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 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, diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt index b805071c521..ce82a5c152f 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt +++ b/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 diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Model.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Model.kt deleted file mode 100644 index be314dcd20a..00000000000 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Model.kt +++ /dev/null @@ -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) diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt index e5c9994f856..36c8f8f44e2 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt +++ b/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", diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt index d269138faec..7da14b44cf5 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt +++ b/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 { - val controller = Controller(settings, BenchmarkSqlStore("postgresql"), PebbleAdapter) + val controller = Controller(settings, BenchmarkSqlStore("postgresql"), PebbleAdapter()) val controllerPath = controller.path val serverHeaderHandler = OnHandler("*") { send(headers = headers) diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/model/CachedWorld.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/model/CachedWorld.kt new file mode 100644 index 00000000000..101176e3c39 --- /dev/null +++ b/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) diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/model/Fortune.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/model/Fortune.kt new file mode 100644 index 00000000000..b4781735ec1 --- /dev/null +++ b/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) diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/model/Message.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/model/Message.kt new file mode 100644 index 00000000000..090dcbf0be6 --- /dev/null +++ b/frameworks/Kotlin/hexagon/src/main/kotlin/model/Message.kt @@ -0,0 +1,3 @@ +package com.hexagonkt.model + +data class Message(val message: String) diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/model/World.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/model/World.kt new file mode 100644 index 00000000000..5f3316f9a5a --- /dev/null +++ b/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) diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkPgClientStore.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkPgClientStore.kt new file mode 100644 index 00000000000..cd467c6c34d --- /dev/null +++ b/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("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 = + 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): List = + ids.map { + findWorld(it, dataSource).toCompletionStage().toCompletableFuture().get() + } + + override fun replaceWorlds(worlds: List) { + 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) { + 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 = + client + .preparedQuery(SELECT_WORLD) + .execute(Tuple.of(id)) + .map { rowSet -> + val row = rowSet.iterator().next() + World(row.getInteger(0), row.getInteger(1)) + } +} diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt index f2d68d7cb6c..157ad7c982c 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt +++ b/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() diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkStore.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkStore.kt index 2c6ce918128..5182fe4ccae 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkStore.kt +++ b/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 From 2eda84c7a5658c100df2b8cfa246149e53b24331 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Tue, 3 Jan 2023 20:20:22 +0100 Subject: [PATCH 077/149] Version updates --- frameworks/Kotlin/hexagon/build.gradle | 15 ++++++++------- .../hexagon/hexagon-jettyloom-pgclient.dockerfile | 2 +- .../Kotlin/hexagon/hexagon-jettyloom.dockerfile | 2 +- .../Kotlin/hexagon/hexagon-netty.dockerfile | 2 +- .../hexagon-nettyepoll-pgclient.dockerfile | 2 +- .../Kotlin/hexagon/hexagon-nettyepoll.dockerfile | 2 +- .../Kotlin/hexagon/hexagon-tomcat.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon.dockerfile | 2 +- 8 files changed, 15 insertions(+), 14 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index ad55d00bcfd..d4830752b19 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,16 +1,17 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "1.7.22" + id "org.jetbrains.kotlin.jvm" version "1.8.0" } ext { - hexagonVersion = "2.2.7" + hexagonVersion = "2.3.1" + hexagonExtraVersion = "2.3.1" hikariVersion = "5.0.1" - jettyVersion = "11.0.12" - postgresqlVersion = "42.5.0" - vertxVersion = "4.3.5" + jettyVersion = "11.0.13" + postgresqlVersion = "42.5.1" + vertxVersion = "4.3.7" cache2kVersion = "2.6.1.Final" - nettyVersion = "4.1.85.Final" + nettyVersion = "4.1.86.Final" gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/$hexagonVersion/gradle" } @@ -49,7 +50,7 @@ dependencies { providedCompile("org.eclipse.jetty:jetty-webapp:$jettyVersion") { exclude module: "slf4j-api" } } -task("minimizeTemplate") { +tasks.register("minimizeTemplate") { doLast { File template = file("$buildDir/resources/main/fortunes.pebble.html") List lines = template.readLines().collect { it.trim() } diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile index 18d9d309d13..0325868b645 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.5.1-jdk17-alpine AS build +FROM gradle:7.6-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile index e681fc03572..2bd37096b09 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.5.1-jdk17-alpine AS build +FROM gradle:7.6-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile index 05c93562cf0..9c11f65f9ae 100644 --- a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.5.1-jdk17-alpine AS build +FROM gradle:7.6-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile index efc4db12aaa..2ceeae57fe7 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.5.1-jdk17-alpine AS build +FROM gradle:7.6-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile index 87260f430e9..31052f788cd 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.5.1-jdk17-alpine AS build +FROM gradle:7.6-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index d15c7180a93..ecef1005aad 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.5.1-jdk17-alpine AS build +FROM gradle:7.6-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index 6edc32dc1dd..45a775be916 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.5.1-jdk17-alpine AS build +FROM gradle:7.6-jdk17-alpine AS build USER root WORKDIR /hexagon From 40afa7e5dbd7c0ee9de65fe2de5326671e47af32 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 6 Jan 2023 19:16:12 +0100 Subject: [PATCH 078/149] Version updates --- frameworks/Kotlin/hexagon/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index d4830752b19..cc2cd56c48b 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -4,8 +4,8 @@ plugins { } ext { - hexagonVersion = "2.3.1" - hexagonExtraVersion = "2.3.1" + hexagonVersion = "2.4.0" + hexagonExtraVersion = "2.4.0" hikariVersion = "5.0.1" jettyVersion = "11.0.13" postgresqlVersion = "42.5.1" From 9515299f484a45c20c031dae153e2eec61a62a90 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sat, 7 Jan 2023 00:28:11 +0100 Subject: [PATCH 079/149] Version updates --- frameworks/Kotlin/hexagon/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index cc2cd56c48b..471454d5304 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -4,7 +4,7 @@ plugins { } ext { - hexagonVersion = "2.4.0" + hexagonVersion = "2.4.1" hexagonExtraVersion = "2.4.0" hikariVersion = "5.0.1" jettyVersion = "11.0.13" From 243d6beadda4666780c77ca12624d8a6d8b2aa6a Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 1 Feb 2023 15:35:16 +0100 Subject: [PATCH 080/149] [Hexagon] Refactor and updates: * Update Hexagon version * Use Rocker template * Modularize the different scenarios --- frameworks/Kotlin/hexagon/build.gradle | 55 ++++-------------- frameworks/Kotlin/hexagon/core/build.gradle | 34 +++++++++++ .../hexagon/core/src/main/kotlin/Benchmark.kt | 27 +++++++++ .../{ => core}/src/main/kotlin/Controller.kt | 25 ++++----- .../{ => core}/src/main/kotlin/Settings.kt | 7 ++- .../src/main/kotlin/model/CachedWorld.kt | 0 .../src/main/kotlin/model/Fortune.kt | 0 .../src/main/kotlin/model/Message.kt | 0 .../{ => core}/src/main/kotlin/model/World.kt | 0 .../src/main/kotlin/store/BenchmarkStore.kt | 0 .../src/main/resources/fortunes.pebble.html | 0 .../src/main/resources/fortunes.rocker.html | 24 ++++++++ .../hexagon-jettyloom-pgclient.dockerfile | 14 ++--- .../hexagon/hexagon-jettyloom.dockerfile | 14 ++--- .../Kotlin/hexagon/hexagon-netty.dockerfile | 16 ++---- .../hexagon-nettyepoll-pgclient.dockerfile | 16 ++---- .../hexagon/hexagon-nettyepoll.dockerfile | 16 ++---- .../Kotlin/hexagon/hexagon-tomcat.dockerfile | 12 ++-- frameworks/Kotlin/hexagon/hexagon.dockerfile | 16 ++---- .../hexagon_jetty_pgclient/build.gradle | 13 +++++ .../src/main/kotlin/Benchmark.kt | 23 ++++++++ .../hexagon_jetty_postgresql/build.gradle | 13 +++++ .../src/main/kotlin/Benchmark.kt | 23 ++++++++ .../hexagon_netty_postgresql/build.gradle | 13 +++++ .../src/main/kotlin/Benchmark.kt | 17 ++++++ .../hexagon_nettyepoll_pgclient/build.gradle | 14 +++++ .../src/main/kotlin/Benchmark.kt | 17 ++++++ .../build.gradle | 14 +++++ .../src/main/kotlin/Benchmark.kt | 17 ++++++ .../hexagon_tomcat_postgresql/build.gradle | 15 +++++ .../src/main/kotlin/WebListenerServer.kt | 12 +++- frameworks/Kotlin/hexagon/settings.gradle | 13 +++++ .../hexagon/src/main/kotlin/Benchmark.kt | 56 ------------------- .../hexagon/store_pgclient/build.gradle | 6 ++ .../main/kotlin}/BenchmarkPgClientStore.kt | 5 +- .../Kotlin/hexagon/store_sql/build.gradle | 6 ++ .../src/main/kotlin}/BenchmarkSqlStore.kt | 2 +- 37 files changed, 367 insertions(+), 188 deletions(-) create mode 100644 frameworks/Kotlin/hexagon/core/build.gradle create mode 100644 frameworks/Kotlin/hexagon/core/src/main/kotlin/Benchmark.kt rename frameworks/Kotlin/hexagon/{ => core}/src/main/kotlin/Controller.kt (88%) rename frameworks/Kotlin/hexagon/{ => core}/src/main/kotlin/Settings.kt (82%) rename frameworks/Kotlin/hexagon/{ => core}/src/main/kotlin/model/CachedWorld.kt (100%) rename frameworks/Kotlin/hexagon/{ => core}/src/main/kotlin/model/Fortune.kt (100%) rename frameworks/Kotlin/hexagon/{ => core}/src/main/kotlin/model/Message.kt (100%) rename frameworks/Kotlin/hexagon/{ => core}/src/main/kotlin/model/World.kt (100%) rename frameworks/Kotlin/hexagon/{ => core}/src/main/kotlin/store/BenchmarkStore.kt (100%) rename frameworks/Kotlin/hexagon/{ => core}/src/main/resources/fortunes.pebble.html (100%) create mode 100644 frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.rocker.html create mode 100644 frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/build.gradle create mode 100644 frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/src/main/kotlin/Benchmark.kt create mode 100644 frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/build.gradle create mode 100644 frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/kotlin/Benchmark.kt create mode 100644 frameworks/Kotlin/hexagon/hexagon_netty_postgresql/build.gradle create mode 100644 frameworks/Kotlin/hexagon/hexagon_netty_postgresql/src/main/kotlin/Benchmark.kt create mode 100644 frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/build.gradle create mode 100644 frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/src/main/kotlin/Benchmark.kt create mode 100644 frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/build.gradle create mode 100644 frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/src/main/kotlin/Benchmark.kt create mode 100644 frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/build.gradle rename frameworks/Kotlin/hexagon/{ => hexagon_tomcat_postgresql}/src/main/kotlin/WebListenerServer.kt (62%) create mode 100644 frameworks/Kotlin/hexagon/settings.gradle delete mode 100644 frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt create mode 100644 frameworks/Kotlin/hexagon/store_pgclient/build.gradle rename frameworks/Kotlin/hexagon/{src/main/kotlin/store => store_pgclient/src/main/kotlin}/BenchmarkPgClientStore.kt (97%) create mode 100644 frameworks/Kotlin/hexagon/store_sql/build.gradle rename frameworks/Kotlin/hexagon/{src/main/kotlin/store => store_sql/src/main/kotlin}/BenchmarkSqlStore.kt (99%) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 471454d5304..c20ee5868d8 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,61 +1,26 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "1.8.0" + id "org.jetbrains.kotlin.jvm" version "1.8.0" apply false } +version = "1.0.0" +description = "TFB benchmark" +group = "com.hexagonkt" + ext { - hexagonVersion = "2.4.1" - hexagonExtraVersion = "2.4.0" + hexagonVersion = "2.5.0" hikariVersion = "5.0.1" jettyVersion = "11.0.13" postgresqlVersion = "42.5.1" vertxVersion = "4.3.7" cache2kVersion = "2.6.1.Final" - nettyVersion = "4.1.86.Final" + nettyVersion = "4.1.87.Final" gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/$hexagonVersion/gradle" } -apply(from: "$gradleScripts/kotlin.gradle") -apply(from: "$gradleScripts/application.gradle") - -apply(plugin: "war") +defaultTasks("build") -defaultTasks("installDist") - -application { - mainClass.set("com.hexagonkt.BenchmarkKt") +subprojects { + apply(from: "$gradleScripts/kotlin.gradle") } - -war { - archiveFileName = "ROOT.war" -} - -installDist.dependsOn("war") - -dependencies { - implementation("com.hexagonkt:http_server_netty_epoll:$hexagonVersion") - implementation("com.hexagonkt:http_server_jetty:$hexagonVersion") - implementation("com.hexagonkt:templates_pebble:$hexagonVersion") - implementation("com.hexagonkt:logging_slf4j_jul:$hexagonVersion") - implementation("com.hexagonkt:serialization_dsl_json:$hexagonVersion") - - implementation("io.netty:netty-transport-native-epoll:$nettyVersion:linux-x86_64") - 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" } -} - -tasks.register("minimizeTemplate") { - doLast { - File template = file("$buildDir/resources/main/fortunes.pebble.html") - List lines = template.readLines().collect { it.trim() } - template.write(lines.join("")) - } -} - -assemble.dependsOn("minimizeTemplate") diff --git a/frameworks/Kotlin/hexagon/core/build.gradle b/frameworks/Kotlin/hexagon/core/build.gradle new file mode 100644 index 00000000000..45d18cda86f --- /dev/null +++ b/frameworks/Kotlin/hexagon/core/build.gradle @@ -0,0 +1,34 @@ + +plugins { + id("nu.studer.rocker") version("3.0.4") +} + +dependencies { + api("com.hexagonkt:http_server:$hexagonVersion") + api("com.hexagonkt:templates_pebble:$hexagonVersion") + api("com.hexagonkt:templates_rocker:$hexagonVersion") + api("com.hexagonkt:logging_slf4j_jul:$hexagonVersion") + api("com.hexagonkt:serialization_dsl_json:$hexagonVersion") + api("org.cache2k:cache2k-core:$cache2kVersion") +} + +tasks.register("minimizeTemplate") { + doLast { + [ "fortunes.pebble.html", "fortunes.rocker.html" ].forEach { t -> + File template = file("$buildDir/resources/main/$t") + List lines = template.readLines().collect { it.trim() } + template.write(lines.join("")) + } + } +} + +jar.dependsOn("minimizeTemplate") + +rocker { + configurations { + create("main") { + templateDir.set(file("src/main/resources")) + optimize.set(true) + } + } +} diff --git a/frameworks/Kotlin/hexagon/core/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/core/src/main/kotlin/Benchmark.kt new file mode 100644 index 00000000000..ef2da876dae --- /dev/null +++ b/frameworks/Kotlin/hexagon/core/src/main/kotlin/Benchmark.kt @@ -0,0 +1,27 @@ +package com.hexagonkt + +import com.hexagonkt.http.server.HttpServer +import com.hexagonkt.http.server.HttpServerPort +import com.hexagonkt.http.server.HttpServerSettings +import com.hexagonkt.store.BenchmarkStore +import com.hexagonkt.templates.TemplatePort +import java.net.InetAddress +import java.net.URL + +class Benchmark( + private val engine: HttpServerPort, + private val store: BenchmarkStore, + private val template: TemplatePort, + private val templateUrl: URL, + private val settings: Settings = Settings(), +) { + val server: HttpServer by lazy { + val controller = Controller(settings, store, template, templateUrl) + val serverSettings = HttpServerSettings( + bindAddress = InetAddress.getByName(settings.bindAddress), + bindPort = settings.bindPort, + ) + + HttpServer(engine, controller.path, serverSettings) + } +} diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt similarity index 88% rename from frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt rename to frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt index ce82a5c152f..4ad7055e8e1 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt @@ -7,10 +7,10 @@ import com.hexagonkt.core.media.TextMedia.PLAIN import com.hexagonkt.http.model.ContentType import com.hexagonkt.http.model.Header import com.hexagonkt.http.model.Headers +import com.hexagonkt.http.server.callbacks.DateCallback 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 @@ -18,7 +18,6 @@ import com.hexagonkt.store.BenchmarkStore import com.hexagonkt.templates.TemplatePort import java.net.URL -import java.time.LocalDateTime.now import java.util.concurrent.ThreadLocalRandom import kotlin.text.Charsets.UTF_8 @@ -27,29 +26,26 @@ class Controller( settings: Settings, store: BenchmarkStore, templateEngine: TemplatePort, + templateUrl: URL, ) { private val queriesParam: String = settings.queriesParam private val cachedQueriesParam: String = settings.cachedQueriesParam private val worldRows: Int = settings.worldRows + private val textMessage: String = settings.textMessage private val plain: ContentType = ContentType(PLAIN) private val json: ContentType = ContentType(JSON) private val html: ContentType = ContentType(HTML, charset = UTF_8) - private val templateUrl: URL = URL("classpath:fortunes.pebble.html") + private val headers = Headers(Header("server", "Hexagon")) - private val headers = Headers( - Header("server", "Hexagon"), - ) - - internal val path: PathHandler by lazy { + val path: PathHandler by lazy { path { - on("*") { - send(headers = headers + Header("date", now().toHttpFormat())) - } + on("*") { send(headers = headers) } + on("*", DateCallback()) - get("/plaintext") { ok(settings.textMessage, contentType = plain) } - get("/json") { ok(Message(settings.textMessage).toMap().serialize(Json.raw), contentType = json) } + get("/plaintext") { ok(textMessage, contentType = plain) } + get("/json") { ok(Message(textMessage).toJson(), contentType = json) } get("/fortunes") { listFortunes(store, templateUrl, templateEngine) } get("/db") { dbQuery(store) } get("/query") { getWorlds(store) } @@ -58,6 +54,9 @@ class Controller( } } + private fun Message.toJson(): String = + toMap().serialize(Json.raw) + private fun HttpServerContext.listFortunes( store: BenchmarkStore, templateUrl: URL, templateAdapter: TemplatePort ): HttpServerContext { diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt b/frameworks/Kotlin/hexagon/core/src/main/kotlin/Settings.kt similarity index 82% rename from frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt rename to frameworks/Kotlin/hexagon/core/src/main/kotlin/Settings.kt index 36c8f8f44e2..b11ed02c9e9 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt +++ b/frameworks/Kotlin/hexagon/core/src/main/kotlin/Settings.kt @@ -1,5 +1,6 @@ package com.hexagonkt +import com.hexagonkt.core.Jvm.systemFlag import com.hexagonkt.core.Jvm.systemSettingOrNull data class Settings( @@ -23,9 +24,9 @@ data class Settings( val databaseName: String = systemSettingOrNull("database") ?: "hello_world", val databaseDriver: String = systemSettingOrNull("databaseDriver") ?: "org.postgresql.Driver", - val sendDateHeader: Boolean = systemSettingOrNull("sendDateHeader") ?: false, - val sendServerVersion: Boolean = systemSettingOrNull("sendServerVersion") ?: false, - val sendXPoweredBy: Boolean = systemSettingOrNull("sendXPoweredBy") ?: false, + val sendDateHeader: Boolean = systemFlag("sendDateHeader"), + val sendServerVersion: Boolean = systemFlag("sendServerVersion"), + val sendXPoweredBy: Boolean = systemFlag("sendXPoweredBy"), val worldRows: Int = 10_000, val textMessage: String = "Hello, World!", diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/model/CachedWorld.kt b/frameworks/Kotlin/hexagon/core/src/main/kotlin/model/CachedWorld.kt similarity index 100% rename from frameworks/Kotlin/hexagon/src/main/kotlin/model/CachedWorld.kt rename to frameworks/Kotlin/hexagon/core/src/main/kotlin/model/CachedWorld.kt diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/model/Fortune.kt b/frameworks/Kotlin/hexagon/core/src/main/kotlin/model/Fortune.kt similarity index 100% rename from frameworks/Kotlin/hexagon/src/main/kotlin/model/Fortune.kt rename to frameworks/Kotlin/hexagon/core/src/main/kotlin/model/Fortune.kt diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/model/Message.kt b/frameworks/Kotlin/hexagon/core/src/main/kotlin/model/Message.kt similarity index 100% rename from frameworks/Kotlin/hexagon/src/main/kotlin/model/Message.kt rename to frameworks/Kotlin/hexagon/core/src/main/kotlin/model/Message.kt diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/model/World.kt b/frameworks/Kotlin/hexagon/core/src/main/kotlin/model/World.kt similarity index 100% rename from frameworks/Kotlin/hexagon/src/main/kotlin/model/World.kt rename to frameworks/Kotlin/hexagon/core/src/main/kotlin/model/World.kt diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkStore.kt b/frameworks/Kotlin/hexagon/core/src/main/kotlin/store/BenchmarkStore.kt similarity index 100% rename from frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkStore.kt rename to frameworks/Kotlin/hexagon/core/src/main/kotlin/store/BenchmarkStore.kt diff --git a/frameworks/Kotlin/hexagon/src/main/resources/fortunes.pebble.html b/frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.pebble.html similarity index 100% rename from frameworks/Kotlin/hexagon/src/main/resources/fortunes.pebble.html rename to frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.pebble.html diff --git a/frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.rocker.html b/frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.rocker.html new file mode 100644 index 00000000000..c9a9d4037e5 --- /dev/null +++ b/frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.rocker.html @@ -0,0 +1,24 @@ +@import java.util.* +@import com.hexagonkt.model.Fortune +@args(Map context) + + + + + Fortunes + + + + + + + + @for ((fortune) : (Collection)context.get("fortunes")) { + + + + + } +
idmessage
@fortune.getId()@fortune.getMessage()
+ + diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile index 0325868b645..c04d91d0118 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile @@ -5,22 +5,18 @@ FROM gradle:7.6-jdk17-alpine AS build USER root WORKDIR /hexagon -COPY src src -COPY build.gradle build.gradle +ADD . . +RUN gradle --quiet compileRocker 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 +ENV PROJECT hexagon_jetty_pgclient +ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA -DvirtualThreads=true -COPY --from=build /hexagon/build/install/$PROJECT /opt/$PROJECT +COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT EXPOSE 9090 diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile index 2bd37096b09..656cf8f03ed 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile @@ -5,22 +5,18 @@ FROM gradle:7.6-jdk17-alpine AS build USER root WORKDIR /hexagon -COPY src src -COPY build.gradle build.gradle +ADD . . +RUN gradle --quiet compileRocker 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 +ENV PROJECT hexagon_jetty_postgresql +ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA -DvirtualThreads=true -COPY --from=build /hexagon/build/install/$PROJECT /opt/$PROJECT +COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT EXPOSE 9090 diff --git a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile index 9c11f65f9ae..c11b0302d41 100644 --- a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile @@ -5,22 +5,18 @@ FROM gradle:7.6-jdk17-alpine AS build USER root WORKDIR /hexagon -COPY src src -COPY build.gradle build.gradle +ADD . . +RUN gradle --quiet compileRocker RUN gradle --quiet -x test # # RUNTIME # -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 +FROM eclipse-temurin:17-jre-alpine +ENV PROJECT hexagon_netty_postgresql +ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA -COPY --from=build /hexagon/build/install/$PROJECT /opt/$PROJECT +COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT EXPOSE 9090 diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile index 2ceeae57fe7..e9d065bbf95 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile @@ -5,22 +5,18 @@ FROM gradle:7.6-jdk17-alpine AS build USER root WORKDIR /hexagon -COPY src src -COPY build.gradle build.gradle +ADD . . +RUN gradle --quiet compileRocker 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 +FROM eclipse-temurin:17-jre-alpine +ENV PROJECT hexagon_nettyepoll_pgclient +ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA -COPY --from=build /hexagon/build/install/$PROJECT /opt/$PROJECT +COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT EXPOSE 9090 diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile index 31052f788cd..c7beb493420 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile @@ -5,22 +5,18 @@ FROM gradle:7.6-jdk17-alpine AS build USER root WORKDIR /hexagon -COPY src src -COPY build.gradle build.gradle +ADD . . +RUN gradle --quiet compileRocker RUN gradle --quiet -x test # # RUNTIME # -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 +FROM eclipse-temurin:17-jre-alpine +ENV PROJECT hexagon_nettyepoll_postgresql +ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA -COPY --from=build /hexagon/build/install/$PROJECT /opt/$PROJECT +COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT EXPOSE 9090 diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index ecef1005aad..c8c2f74a319 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -5,18 +5,16 @@ FROM gradle:7.6-jdk17-alpine AS build USER root WORKDIR /hexagon -COPY src src -COPY build.gradle build.gradle +ADD . . +RUN gradle --quiet compileRocker RUN gradle --quiet -x test # # RUNTIME # 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 +ENV MODULE /hexagon/hexagon_tomcat_postgresql +ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA -COPY --from=build /hexagon/build/libs/ROOT.war /usr/local/tomcat/webapps/ROOT.war +COPY --from=build $MODULE/build/libs/ROOT.war /usr/local/tomcat/webapps/ROOT.war EXPOSE 8080 diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index 45a775be916..2d1ee3d3819 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -5,22 +5,18 @@ FROM gradle:7.6-jdk17-alpine AS build USER root WORKDIR /hexagon -COPY src src -COPY build.gradle build.gradle +ADD . . +RUN gradle --quiet compileRocker RUN gradle --quiet -x test # # RUNTIME # -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 +FROM eclipse-temurin:17-jre-alpine +ENV PROJECT hexagon_jetty_postgresql +ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA -COPY --from=build /hexagon/build/install/$PROJECT /opt/$PROJECT +COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT EXPOSE 9090 diff --git a/frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/build.gradle b/frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/build.gradle new file mode 100644 index 00000000000..71e2dc0f44f --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/build.gradle @@ -0,0 +1,13 @@ + +apply(from: "$gradleScripts/application.gradle") + +application { + mainClass.set("com.hexagonkt.BenchmarkKt") +} + +dependencies { + api(project(":store_pgclient")) + api("com.hexagonkt:http_server_jetty:$hexagonVersion") +} + +build.dependsOn("installDist") diff --git a/frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/src/main/kotlin/Benchmark.kt new file mode 100644 index 00000000000..983831ad866 --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/src/main/kotlin/Benchmark.kt @@ -0,0 +1,23 @@ +package com.hexagonkt + +import com.hexagonkt.core.Jvm.systemFlag +import com.hexagonkt.http.server.jetty.JettyServletAdapter +import com.hexagonkt.store.BenchmarkPgClientStore +import com.hexagonkt.templates.rocker.RockerAdapter +import java.net.URL + +fun main() { + val settings = Settings() + val store = BenchmarkPgClientStore("postgresql") + val templateEngine = RockerAdapter() + val templateUrl = URL("classpath:fortunes.rocker.html") + val engine = JettyServletAdapter( + sendDateHeader = settings.sendDateHeader, + sendServerVersion = settings.sendServerVersion, + sendXPoweredBy = settings.sendXPoweredBy, + useVirtualThreads = systemFlag("virtualThreads"), + ) + + val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) + benchmark.server.start() +} diff --git a/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/build.gradle b/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/build.gradle new file mode 100644 index 00000000000..09dde4a8327 --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/build.gradle @@ -0,0 +1,13 @@ + +apply(from: "$gradleScripts/application.gradle") + +application { + mainClass.set("com.hexagonkt.BenchmarkKt") +} + +dependencies { + api(project(":store_sql")) + api("com.hexagonkt:http_server_jetty:$hexagonVersion") +} + +build.dependsOn("installDist") diff --git a/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/kotlin/Benchmark.kt new file mode 100644 index 00000000000..1ba499672b8 --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/kotlin/Benchmark.kt @@ -0,0 +1,23 @@ +package com.hexagonkt + +import com.hexagonkt.core.Jvm.systemFlag +import com.hexagonkt.http.server.jetty.JettyServletAdapter +import com.hexagonkt.store.BenchmarkSqlStore +import com.hexagonkt.templates.rocker.RockerAdapter +import java.net.URL + +fun main() { + val settings = Settings() + val store = BenchmarkSqlStore("postgresql") + val templateEngine = RockerAdapter() + val templateUrl = URL("classpath:fortunes.rocker.html") + val engine = JettyServletAdapter( + sendDateHeader = settings.sendDateHeader, + sendServerVersion = settings.sendServerVersion, + sendXPoweredBy = settings.sendXPoweredBy, + useVirtualThreads = systemFlag("virtualThreads"), + ) + + val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) + benchmark.server.start() +} diff --git a/frameworks/Kotlin/hexagon/hexagon_netty_postgresql/build.gradle b/frameworks/Kotlin/hexagon/hexagon_netty_postgresql/build.gradle new file mode 100644 index 00000000000..e06ac14aff0 --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_netty_postgresql/build.gradle @@ -0,0 +1,13 @@ + +apply(from: "$gradleScripts/application.gradle") + +application { + mainClass.set("com.hexagonkt.BenchmarkKt") +} + +dependencies { + api(project(":store_sql")) + api("com.hexagonkt:http_server_netty:$hexagonVersion") +} + +build.dependsOn("installDist") diff --git a/frameworks/Kotlin/hexagon/hexagon_netty_postgresql/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_netty_postgresql/src/main/kotlin/Benchmark.kt new file mode 100644 index 00000000000..100af29d51e --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_netty_postgresql/src/main/kotlin/Benchmark.kt @@ -0,0 +1,17 @@ +package com.hexagonkt + +import com.hexagonkt.http.server.netty.NettyServerAdapter +import com.hexagonkt.store.BenchmarkSqlStore +import com.hexagonkt.templates.rocker.RockerAdapter +import java.net.URL + +fun main() { + val settings = Settings() + val store = BenchmarkSqlStore("postgresql") + val templateEngine = RockerAdapter() + val templateUrl = URL("classpath:fortunes.rocker.html") + val engine = NettyServerAdapter() + + val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) + benchmark.server.start() +} diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/build.gradle b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/build.gradle new file mode 100644 index 00000000000..07ecf663690 --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/build.gradle @@ -0,0 +1,14 @@ + +apply(from: "$gradleScripts/application.gradle") + +application { + mainClass.set("com.hexagonkt.BenchmarkKt") +} + +dependencies { + api(project(":store_pgclient")) + api("com.hexagonkt:http_server_netty_epoll:$hexagonVersion") + api("io.netty:netty-transport-native-epoll:$nettyVersion:linux-x86_64") +} + +build.dependsOn("installDist") diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/src/main/kotlin/Benchmark.kt new file mode 100644 index 00000000000..abe085171f2 --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/src/main/kotlin/Benchmark.kt @@ -0,0 +1,17 @@ +package com.hexagonkt + +import com.hexagonkt.http.server.netty.epoll.NettyEpollServerAdapter +import com.hexagonkt.store.BenchmarkPgClientStore +import com.hexagonkt.templates.rocker.RockerAdapter +import java.net.URL + +fun main() { + val settings = Settings() + val store = BenchmarkPgClientStore("postgresql") + val templateEngine = RockerAdapter() + val templateUrl = URL("classpath:fortunes.rocker.html") + val engine = NettyEpollServerAdapter() + + val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) + benchmark.server.start() +} diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/build.gradle b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/build.gradle new file mode 100644 index 00000000000..b314102ff80 --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/build.gradle @@ -0,0 +1,14 @@ + +apply(from: "$gradleScripts/application.gradle") + +application { + mainClass.set("com.hexagonkt.BenchmarkKt") +} + +dependencies { + api(project(":store_sql")) + api("com.hexagonkt:http_server_netty_epoll:$hexagonVersion") + api("io.netty:netty-transport-native-epoll:$nettyVersion:linux-x86_64") +} + +build.dependsOn("installDist") diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/src/main/kotlin/Benchmark.kt new file mode 100644 index 00000000000..d0c2aa58347 --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/src/main/kotlin/Benchmark.kt @@ -0,0 +1,17 @@ +package com.hexagonkt + +import com.hexagonkt.http.server.netty.epoll.NettyEpollServerAdapter +import com.hexagonkt.store.BenchmarkSqlStore +import com.hexagonkt.templates.rocker.RockerAdapter +import java.net.URL + +fun main() { + val settings = Settings() + val store = BenchmarkSqlStore("postgresql") + val templateEngine = RockerAdapter() + val templateUrl = URL("classpath:fortunes.rocker.html") + val engine = NettyEpollServerAdapter() + + val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) + benchmark.server.start() +} diff --git a/frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/build.gradle b/frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/build.gradle new file mode 100644 index 00000000000..3c72b9d4b0a --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/build.gradle @@ -0,0 +1,15 @@ + +apply(plugin: "war") + +war { + archiveFileName = "ROOT.war" +} + +build.dependsOn("war") + +dependencies { + api(project(":store_sql")) + api("com.hexagonkt:http_server_servlet:$hexagonVersion") + + compileOnly("jakarta.servlet:jakarta.servlet-api:5.0.0") +} diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt b/frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/src/main/kotlin/WebListenerServer.kt similarity index 62% rename from frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt rename to frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/src/main/kotlin/WebListenerServer.kt index 7da14b44cf5..cdf911e1ee9 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt +++ b/frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/src/main/kotlin/WebListenerServer.kt @@ -6,16 +6,22 @@ import com.hexagonkt.http.server.handlers.HttpHandler import com.hexagonkt.http.server.handlers.OnHandler import com.hexagonkt.http.server.servlet.ServletServer import com.hexagonkt.store.BenchmarkSqlStore -import com.hexagonkt.templates.pebble.PebbleAdapter +import com.hexagonkt.templates.rocker.RockerAdapter import jakarta.servlet.annotation.WebListener +import java.net.URL -@WebListener class WebListenerServer(settings: Settings = Settings()) : ServletServer(createHandlers(settings)) { +@WebListener class WebListenerServer( + settings: Settings = Settings() +) : ServletServer(createHandlers(settings)) { private companion object { val headers = Headers(Header("server", "Tomcat")) fun createHandlers(settings: Settings): List { - val controller = Controller(settings, BenchmarkSqlStore("postgresql"), PebbleAdapter()) + val store = BenchmarkSqlStore("postgresql") + val templateEngine = RockerAdapter() + val templateUrl = URL("classpath:fortunes.rocker.html") + val controller = Controller(settings, store, templateEngine, templateUrl) val controllerPath = controller.path val serverHeaderHandler = OnHandler("*") { send(headers = headers) diff --git a/frameworks/Kotlin/hexagon/settings.gradle b/frameworks/Kotlin/hexagon/settings.gradle new file mode 100644 index 00000000000..2d571cdc706 --- /dev/null +++ b/frameworks/Kotlin/hexagon/settings.gradle @@ -0,0 +1,13 @@ + +include( + "core", + "store_pgclient", + "store_sql", + + "hexagon_jetty_pgclient", + "hexagon_jetty_postgresql", + "hexagon_netty_postgresql", + "hexagon_nettyepoll_pgclient", + "hexagon_nettyepoll_postgresql", + "hexagon_tomcat_postgresql", +) diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt deleted file mode 100644 index a296a9d261d..00000000000 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt +++ /dev/null @@ -1,56 +0,0 @@ -package com.hexagonkt - -import com.hexagonkt.http.server.HttpServer -import com.hexagonkt.http.server.HttpServerPort -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 - -internal val settings = Settings() - -private val engines: Map by lazy { - mapOf( - "jetty" to JettyServletAdapter( - sendDateHeader = settings.sendDateHeader, - 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 stores: Map 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 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, - ) - - HttpServer(engine, controller.path, serverSettings) -} - -fun main() { - server.start() -} diff --git a/frameworks/Kotlin/hexagon/store_pgclient/build.gradle b/frameworks/Kotlin/hexagon/store_pgclient/build.gradle new file mode 100644 index 00000000000..6d0c88ad20e --- /dev/null +++ b/frameworks/Kotlin/hexagon/store_pgclient/build.gradle @@ -0,0 +1,6 @@ + +dependencies { + api(project(":core")) + implementation("io.vertx:vertx-pg-client:$vertxVersion") + implementation("com.ongres.scram:client:2.1") +} diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkPgClientStore.kt b/frameworks/Kotlin/hexagon/store_pgclient/src/main/kotlin/BenchmarkPgClientStore.kt similarity index 97% rename from frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkPgClientStore.kt rename to frameworks/Kotlin/hexagon/store_pgclient/src/main/kotlin/BenchmarkPgClientStore.kt index cd467c6c34d..5cd13ccee0a 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkPgClientStore.kt +++ b/frameworks/Kotlin/hexagon/store_pgclient/src/main/kotlin/BenchmarkPgClientStore.kt @@ -11,8 +11,9 @@ import io.vertx.pgclient.PgPool import io.vertx.sqlclient.* import org.cache2k.Cache -internal class BenchmarkPgClientStore( - engine: String, private val settings: Settings = Settings() +class BenchmarkPgClientStore( + engine: String, + private val settings: Settings = Settings(), ) : BenchmarkStore(settings) { companion object { diff --git a/frameworks/Kotlin/hexagon/store_sql/build.gradle b/frameworks/Kotlin/hexagon/store_sql/build.gradle new file mode 100644 index 00000000000..f154eb6dbae --- /dev/null +++ b/frameworks/Kotlin/hexagon/store_sql/build.gradle @@ -0,0 +1,6 @@ + +dependencies { + api(project(":core")) + implementation("com.zaxxer:HikariCP:$hikariVersion") + implementation("org.postgresql:postgresql:$postgresqlVersion") +} diff --git a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt b/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt similarity index 99% rename from frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt rename to frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt index 157ad7c982c..ea871ec1b13 100644 --- a/frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt +++ b/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt @@ -11,7 +11,7 @@ import org.cache2k.Cache import java.sql.Connection import java.sql.PreparedStatement -internal class BenchmarkSqlStore( +class BenchmarkSqlStore( engine: String, private val settings: Settings = Settings() ) : BenchmarkStore(settings) { From 90717cc577e1b5b6882b6b632d2eff6223456031 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 1 Feb 2023 16:03:10 +0100 Subject: [PATCH 081/149] Fix connection problems --- frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile | 1 + frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile | 1 + frameworks/Kotlin/hexagon/hexagon-netty.dockerfile | 1 + frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile | 1 + frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile | 1 + frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile | 1 + frameworks/Kotlin/hexagon/hexagon.dockerfile | 1 + 7 files changed, 7 insertions(+) diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile index c04d91d0118..388fd1036b2 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile @@ -13,6 +13,7 @@ RUN gradle --quiet -x test # RUNTIME # FROM eclipse-temurin:19-jre-alpine +ENV POSTGRESQL_DB_HOST tfb-database ENV PROJECT hexagon_jetty_pgclient ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA -DvirtualThreads=true diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile index 656cf8f03ed..ccf6f8711ee 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile @@ -13,6 +13,7 @@ RUN gradle --quiet -x test # RUNTIME # FROM eclipse-temurin:19-jre-alpine +ENV POSTGRESQL_DB_HOST tfb-database ENV PROJECT hexagon_jetty_postgresql ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA -DvirtualThreads=true diff --git a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile index c11b0302d41..687f0ce38d1 100644 --- a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile @@ -13,6 +13,7 @@ RUN gradle --quiet -x test # RUNTIME # FROM eclipse-temurin:17-jre-alpine +ENV POSTGRESQL_DB_HOST tfb-database ENV PROJECT hexagon_netty_postgresql ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile index e9d065bbf95..f3f948746da 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile @@ -13,6 +13,7 @@ RUN gradle --quiet -x test # RUNTIME # FROM eclipse-temurin:17-jre-alpine +ENV POSTGRESQL_DB_HOST tfb-database ENV PROJECT hexagon_nettyepoll_pgclient ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile index c7beb493420..1bfd11780d3 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile @@ -13,6 +13,7 @@ RUN gradle --quiet -x test # RUNTIME # FROM eclipse-temurin:17-jre-alpine +ENV POSTGRESQL_DB_HOST tfb-database ENV PROJECT hexagon_nettyepoll_postgresql ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index c8c2f74a319..677823b9ba7 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -13,6 +13,7 @@ RUN gradle --quiet -x test # RUNTIME # FROM tomcat:10.1.2-jre17-temurin +ENV POSTGRESQL_DB_HOST tfb-database ENV MODULE /hexagon/hexagon_tomcat_postgresql ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index 2d1ee3d3819..d0e259d10e0 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -13,6 +13,7 @@ RUN gradle --quiet -x test # RUNTIME # FROM eclipse-temurin:17-jre-alpine +ENV POSTGRESQL_DB_HOST tfb-database ENV PROJECT hexagon_jetty_postgresql ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA From 45f074343d0025f2a5d1e0613d5c4de9008543aa Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 9 Mar 2023 18:25:35 +0100 Subject: [PATCH 082/149] Update Hexagon --- frameworks/Kotlin/hexagon/build.gradle | 12 ++++++------ .../hexagon/core/src/main/kotlin/Controller.kt | 14 ++++++-------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index c20ee5868d8..31ab9116d9d 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,6 +1,6 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "1.8.0" apply false + id "org.jetbrains.kotlin.jvm" version "1.8.10" apply false } version = "1.0.0" @@ -8,13 +8,13 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "2.5.0" + hexagonVersion = "2.6.3" hikariVersion = "5.0.1" - jettyVersion = "11.0.13" - postgresqlVersion = "42.5.1" - vertxVersion = "4.3.7" + jettyVersion = "11.0.14" + postgresqlVersion = "42.5.4" + vertxVersion = "4.4.0" cache2kVersion = "2.6.1.Final" - nettyVersion = "4.1.87.Final" + nettyVersion = "4.1.89.Final" gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/$hexagonVersion/gradle" } diff --git a/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt index 4ad7055e8e1..c747fa889e9 100644 --- a/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt @@ -1,9 +1,9 @@ package com.hexagonkt import com.hexagonkt.core.fieldsMapOf -import com.hexagonkt.core.media.ApplicationMedia.JSON -import com.hexagonkt.core.media.TextMedia.HTML -import com.hexagonkt.core.media.TextMedia.PLAIN +import com.hexagonkt.core.media.APPLICATION_JSON +import com.hexagonkt.core.media.TEXT_HTML +import com.hexagonkt.core.media.TEXT_PLAIN import com.hexagonkt.http.model.ContentType import com.hexagonkt.http.model.Header import com.hexagonkt.http.model.Headers @@ -16,10 +16,8 @@ import com.hexagonkt.serialization.dsl.json.Json import com.hexagonkt.serialization.serialize import com.hexagonkt.store.BenchmarkStore import com.hexagonkt.templates.TemplatePort - import java.net.URL import java.util.concurrent.ThreadLocalRandom - import kotlin.text.Charsets.UTF_8 class Controller( @@ -33,9 +31,9 @@ class Controller( private val worldRows: Int = settings.worldRows private val textMessage: String = settings.textMessage - private val plain: ContentType = ContentType(PLAIN) - private val json: ContentType = ContentType(JSON) - private val html: ContentType = ContentType(HTML, charset = UTF_8) + private val plain: ContentType = ContentType(TEXT_PLAIN) + private val json: ContentType = ContentType(APPLICATION_JSON) + private val html: ContentType = ContentType(TEXT_HTML, charset = UTF_8) private val headers = Headers(Header("server", "Hexagon")) From 5df374d3f34b034f9175d7f644501c1f6ed70f97 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 9 Mar 2023 18:55:41 +0100 Subject: [PATCH 083/149] Update Gradle --- .../Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties | 2 +- frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon-netty.dockerfile | 2 +- .../Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon.dockerfile | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties index 3f4def4a917..f0ae57febc4 100644 --- a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties +++ b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https://services.gradle.org/distributions/gradle-7.6-bin.zip +distributionUrl=https://services.gradle.org/distributions/gradle-8.0.2-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile index 388fd1036b2..f047e7e599b 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.6-jdk17-alpine AS build +FROM gradle:8.0.2-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile index ccf6f8711ee..18963d4dfe1 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.6-jdk17-alpine AS build +FROM gradle:8.0.2-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile index 687f0ce38d1..e343078fb6e 100644 --- a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.6-jdk17-alpine AS build +FROM gradle:8.0.2-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile index f3f948746da..d40959b0e0e 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.6-jdk17-alpine AS build +FROM gradle:8.0.2-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile index 1bfd11780d3..575378b8583 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.6-jdk17-alpine AS build +FROM gradle:8.0.2-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index 677823b9ba7..7ca5725be48 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.6-jdk17-alpine AS build +FROM gradle:8.0.2-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index d0e259d10e0..e228bd5a7db 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM gradle:7.6-jdk17-alpine AS build +FROM gradle:8.0.2-jdk17-alpine AS build USER root WORKDIR /hexagon From 8978ca1c145fa3ee44cee04fed604197abed8d32 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sun, 19 Mar 2023 16:41:10 +0100 Subject: [PATCH 084/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 6 +++--- frameworks/Kotlin/hexagon/core/build.gradle | 3 +-- .../Kotlin/hexagon/core/src/main/kotlin/Controller.kt | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 31ab9116d9d..6b15fbd1da9 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -8,13 +8,13 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "2.6.3" + hexagonVersion = "2.6.5" hikariVersion = "5.0.1" jettyVersion = "11.0.14" - postgresqlVersion = "42.5.4" + postgresqlVersion = "42.6.0" vertxVersion = "4.4.0" cache2kVersion = "2.6.1.Final" - nettyVersion = "4.1.89.Final" + nettyVersion = "4.1.90.Final" gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/$hexagonVersion/gradle" } diff --git a/frameworks/Kotlin/hexagon/core/build.gradle b/frameworks/Kotlin/hexagon/core/build.gradle index 45d18cda86f..af7552398d3 100644 --- a/frameworks/Kotlin/hexagon/core/build.gradle +++ b/frameworks/Kotlin/hexagon/core/build.gradle @@ -5,10 +5,9 @@ plugins { dependencies { api("com.hexagonkt:http_server:$hexagonVersion") - api("com.hexagonkt:templates_pebble:$hexagonVersion") api("com.hexagonkt:templates_rocker:$hexagonVersion") api("com.hexagonkt:logging_slf4j_jul:$hexagonVersion") - api("com.hexagonkt:serialization_dsl_json:$hexagonVersion") + api("com.hexagonkt:serialization_jackson_json:$hexagonVersion") api("org.cache2k:cache2k-core:$cache2kVersion") } diff --git a/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt index c747fa889e9..b4714a76049 100644 --- a/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt @@ -12,7 +12,7 @@ import com.hexagonkt.http.server.handlers.HttpServerContext import com.hexagonkt.http.server.handlers.PathHandler import com.hexagonkt.http.server.handlers.path import com.hexagonkt.model.* -import com.hexagonkt.serialization.dsl.json.Json +import com.hexagonkt.serialization.jackson.json.Json import com.hexagonkt.serialization.serialize import com.hexagonkt.store.BenchmarkStore import com.hexagonkt.templates.TemplatePort From 370a13223bc2dbe1df194e9980a19f95d94b9ab2 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Mon, 20 Mar 2023 14:20:58 +0100 Subject: [PATCH 085/149] Update Hexagon version --- frameworks/Kotlin/hexagon/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 6b15fbd1da9..4aad4ab8f98 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -8,7 +8,7 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "2.6.5" + hexagonVersion = "2.6.6" hikariVersion = "5.0.1" jettyVersion = "11.0.14" postgresqlVersion = "42.6.0" From 147afa02f39d62659a37954c2bbeeb77798e51e7 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 30 Mar 2023 19:56:54 +0200 Subject: [PATCH 086/149] Update Gradle Wrapper --- .../hexagon/gradle/wrapper/gradle-wrapper.jar | Bin 61574 -> 61608 bytes frameworks/Kotlin/hexagon/gradlew | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar index 943f0cbfa754578e88a3dae77fce6e3dea56edbf..ccebba7710deaf9f98673a68957ea02138b60d0a 100644 GIT binary patch delta 5094 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 delta 5107 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 I6Xdi10eY*&F8}}l diff --git a/frameworks/Kotlin/hexagon/gradlew b/frameworks/Kotlin/hexagon/gradlew index 65dcd68d65c..79a61d421cc 100755 --- a/frameworks/Kotlin/hexagon/gradlew +++ b/frameworks/Kotlin/hexagon/gradlew @@ -144,7 +144,7 @@ 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 + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +152,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac From 89352f11b0173bd30053c9a4381af7dc10cdaba3 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 7 Jun 2023 13:39:48 +0200 Subject: [PATCH 087/149] Add async and native support --- frameworks/Kotlin/hexagon/.dockerignore | 2 + frameworks/Kotlin/hexagon/build.gradle | 19 ++- frameworks/Kotlin/hexagon/core/build.gradle | 9 +- .../core/src/main/kotlin/Controller.kt | 24 ++-- .../core/native-image.properties | 7 + .../core/reflect-config.json | 23 +++ .../src/main/resources/fortunes.pebble.html | 21 --- .../Kotlin/hexagon/core_async/build.gradle | 32 +++++ .../core_async/src/main/kotlin/Benchmark.kt | 28 ++++ .../core_async/src/main/kotlin/Controller.kt | 133 ++++++++++++++++++ .../src/main/kotlin/store/BenchmarkStore.kt | 34 +++++ .../core/native-image.properties | 7 + .../core/reflect-config.json | 23 +++ .../src/main/resources/fortunes.rocker.html | 24 ++++ .../hexagon/gradle/wrapper/gradle-wrapper.jar | Bin 61608 -> 62076 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- frameworks/Kotlin/hexagon/gradlew | 7 +- .../hexagon/hexagon-jetty-native.dockerfile | 21 +++ .../hexagon-jettyloom-pgclient.dockerfile | 15 +- .../hexagon/hexagon-jettyloom.dockerfile | 15 +- .../hexagon/hexagon-netty-native.dockerfile | 21 +++ .../Kotlin/hexagon/hexagon-netty.dockerfile | 15 +- .../hexagon-nettyepoll-pgclient.dockerfile | 15 +- .../hexagon/hexagon-nettyepoll.dockerfile | 15 +- .../Kotlin/hexagon/hexagon-tomcat.dockerfile | 10 +- frameworks/Kotlin/hexagon/hexagon.dockerfile | 15 +- .../hexagon_jetty_pgclient/build.gradle | 6 - .../hexagon_jetty_postgresql/build.gradle | 7 +- .../hexagon_netty_async_pgclient/build.gradle | 7 + .../src/main/kotlin/Benchmark.kt | 25 ++++ .../hexagon_netty_postgresql/build.gradle | 7 +- .../src/main/kotlin/Benchmark.kt | 7 + .../hexagon_nettyepoll_pgclient/build.gradle | 6 - .../src/main/kotlin/Benchmark.kt | 7 + .../build.gradle | 6 - .../src/main/kotlin/Benchmark.kt | 7 + .../src/main/kotlin/WebListenerServer.kt | 4 +- .../hexagon_vertx_pgclient/build.gradle | 9 ++ .../src/main/kotlin/Benchmark.kt | 33 +++++ frameworks/Kotlin/hexagon/model/build.gradle | 4 + .../src/main/kotlin/Settings.kt | 0 .../src/main/kotlin/model/CachedWorld.kt | 0 .../src/main/kotlin/model/Fortune.kt | 0 .../src/main/kotlin/model/Message.kt | 0 .../src/main/kotlin/model/World.kt | 0 frameworks/Kotlin/hexagon/settings.gradle | 5 + .../hexagon/store_pgclient_async/build.gradle | 6 + .../src/main/kotlin/BenchmarkPgClientStore.kt | 114 +++++++++++++++ 48 files changed, 663 insertions(+), 134 deletions(-) create mode 100644 frameworks/Kotlin/hexagon/.dockerignore create mode 100644 frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties create mode 100644 frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/reflect-config.json delete mode 100644 frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.pebble.html create mode 100644 frameworks/Kotlin/hexagon/core_async/build.gradle create mode 100644 frameworks/Kotlin/hexagon/core_async/src/main/kotlin/Benchmark.kt create mode 100644 frameworks/Kotlin/hexagon/core_async/src/main/kotlin/Controller.kt create mode 100644 frameworks/Kotlin/hexagon/core_async/src/main/kotlin/store/BenchmarkStore.kt create mode 100644 frameworks/Kotlin/hexagon/core_async/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties create mode 100644 frameworks/Kotlin/hexagon/core_async/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/reflect-config.json create mode 100644 frameworks/Kotlin/hexagon/core_async/src/main/resources/fortunes.rocker.html create mode 100644 frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile create mode 100644 frameworks/Kotlin/hexagon/hexagon-netty-native.dockerfile create mode 100644 frameworks/Kotlin/hexagon/hexagon_netty_async_pgclient/build.gradle create mode 100644 frameworks/Kotlin/hexagon/hexagon_netty_async_pgclient/src/main/kotlin/Benchmark.kt create mode 100644 frameworks/Kotlin/hexagon/hexagon_vertx_pgclient/build.gradle create mode 100644 frameworks/Kotlin/hexagon/hexagon_vertx_pgclient/src/main/kotlin/Benchmark.kt create mode 100644 frameworks/Kotlin/hexagon/model/build.gradle rename frameworks/Kotlin/hexagon/{core => model}/src/main/kotlin/Settings.kt (100%) rename frameworks/Kotlin/hexagon/{core => model}/src/main/kotlin/model/CachedWorld.kt (100%) rename frameworks/Kotlin/hexagon/{core => model}/src/main/kotlin/model/Fortune.kt (100%) rename frameworks/Kotlin/hexagon/{core => model}/src/main/kotlin/model/Message.kt (100%) rename frameworks/Kotlin/hexagon/{core => model}/src/main/kotlin/model/World.kt (100%) create mode 100644 frameworks/Kotlin/hexagon/store_pgclient_async/build.gradle create mode 100644 frameworks/Kotlin/hexagon/store_pgclient_async/src/main/kotlin/BenchmarkPgClientStore.kt diff --git a/frameworks/Kotlin/hexagon/.dockerignore b/frameworks/Kotlin/hexagon/.dockerignore new file mode 100644 index 00000000000..5b154f2de67 --- /dev/null +++ b/frameworks/Kotlin/hexagon/.dockerignore @@ -0,0 +1,2 @@ + +**/build/ diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 4aad4ab8f98..755096930bc 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,6 +1,7 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "1.8.10" apply false + id "org.jetbrains.kotlin.jvm" version "1.8.21" apply false + id "org.graalvm.buildtools.native" version "0.9.22" apply false } version = "1.0.0" @@ -8,19 +9,23 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "2.6.6" + hexagonVersion = "3.0.0-B1" + jettyVersion = "11.0.15" + nettyVersion = "4.1.93.Final" + hikariVersion = "5.0.1" - jettyVersion = "11.0.14" postgresqlVersion = "42.6.0" - vertxVersion = "4.4.0" + vertxVersion = "4.4.2" cache2kVersion = "2.6.1.Final" - nettyVersion = "4.1.90.Final" + applicationClass = "com.hexagonkt.BenchmarkKt" + modules = "java.naming,java.sql,java.management" + options = "--enable-preview" gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/$hexagonVersion/gradle" } -defaultTasks("build") - subprojects { + version = rootProject.version + apply(from: "$gradleScripts/kotlin.gradle") } diff --git a/frameworks/Kotlin/hexagon/core/build.gradle b/frameworks/Kotlin/hexagon/core/build.gradle index af7552398d3..4cf6f44b80c 100644 --- a/frameworks/Kotlin/hexagon/core/build.gradle +++ b/frameworks/Kotlin/hexagon/core/build.gradle @@ -4,6 +4,7 @@ plugins { } dependencies { + api(project(":model")) api("com.hexagonkt:http_server:$hexagonVersion") api("com.hexagonkt:templates_rocker:$hexagonVersion") api("com.hexagonkt:logging_slf4j_jul:$hexagonVersion") @@ -13,11 +14,9 @@ dependencies { tasks.register("minimizeTemplate") { doLast { - [ "fortunes.pebble.html", "fortunes.rocker.html" ].forEach { t -> - File template = file("$buildDir/resources/main/$t") - List lines = template.readLines().collect { it.trim() } - template.write(lines.join("")) - } + File template = file("$buildDir/resources/main/fortunes.rocker.html") + List lines = template.readLines().collect { it.trim() } + template.write(lines.join("")) } } diff --git a/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt index b4714a76049..37ab786e791 100644 --- a/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt @@ -8,9 +8,9 @@ import com.hexagonkt.http.model.ContentType import com.hexagonkt.http.model.Header import com.hexagonkt.http.model.Headers import com.hexagonkt.http.server.callbacks.DateCallback -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.handlers.HttpContext +import com.hexagonkt.http.handlers.PathHandler +import com.hexagonkt.http.handlers.path import com.hexagonkt.model.* import com.hexagonkt.serialization.jackson.json.Json import com.hexagonkt.serialization.serialize @@ -55,9 +55,9 @@ class Controller( private fun Message.toJson(): String = toMap().serialize(Json.raw) - private fun HttpServerContext.listFortunes( + private fun HttpContext.listFortunes( store: BenchmarkStore, templateUrl: URL, templateAdapter: TemplatePort - ): HttpServerContext { + ): HttpContext { val fortunes = store.findAllFortunes() + Fortune(0, "Additional fortune added at request time.") val sortedFortunes = fortunes.sortedBy { it.message } @@ -67,7 +67,7 @@ class Controller( return ok(body, contentType = html) } - private fun HttpServerContext.dbQuery(store: BenchmarkStore): HttpServerContext { + private fun HttpContext.dbQuery(store: BenchmarkStore): HttpContext { val ids = listOf(randomWorld()) val worlds = store.findWorlds(ids) val world = worlds.first().toMap() @@ -75,7 +75,7 @@ class Controller( return sendJson(world) } - private fun HttpServerContext.getWorlds(store: BenchmarkStore): HttpServerContext { + private fun HttpContext.getWorlds(store: BenchmarkStore): HttpContext { val worldsCount = getWorldsCount(queriesParam) val ids = (1..worldsCount).map { randomWorld() } val worlds = store.findWorlds(ids).map { it.toMap() } @@ -83,7 +83,7 @@ class Controller( return sendJson(worlds) } - private fun HttpServerContext.getCachedWorlds(store: BenchmarkStore): HttpServerContext { + private fun HttpContext.getCachedWorlds(store: BenchmarkStore): HttpContext { val worldsCount = getWorldsCount(cachedQueriesParam) val ids = (1..worldsCount).map { randomWorld() } val worlds = store.findCachedWorlds(ids).map { it.toMap() } @@ -91,7 +91,7 @@ class Controller( return sendJson(worlds) } - private fun HttpServerContext.updateWorlds(store: BenchmarkStore): HttpServerContext { + private fun HttpContext.updateWorlds(store: BenchmarkStore): HttpContext { val worldsCount = getWorldsCount(queriesParam) val worlds = (1..worldsCount).map { World(randomWorld(), randomWorld()) } @@ -100,11 +100,11 @@ class Controller( return sendJson(worlds.map { it.toMap() }) } - private fun HttpServerContext.sendJson(body: Any): HttpServerContext = + private fun HttpContext.sendJson(body: Any): HttpContext = ok(body.serialize(Json.raw), contentType = json) - private fun HttpServerContext.getWorldsCount(parameter: String): Int = - request.queryParameters[parameter]?.value?.toIntOrNull().let { + private fun HttpContext.getWorldsCount(parameter: String): Int = + request.queryParameters[parameter]?.string()?.toIntOrNull().let { when { it == null -> 1 it < 1 -> 1 diff --git a/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties new file mode 100644 index 00000000000..ee1c0199d95 --- /dev/null +++ b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties @@ -0,0 +1,7 @@ +Args= \ + -H:IncludeResources=.*\\.(html|class) \ + --enable-preview \ + --static \ + --initialize-at-build-time=org.slf4j.jul.JDK14LoggerAdapter \ + --initialize-at-build-time=org.slf4j.jul.JDK14LoggerAdapter$1 \ + --initialize-at-build-time=org.slf4j.LoggerFactory diff --git a/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/reflect-config.json b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/reflect-config.json new file mode 100644 index 00000000000..11815306be2 --- /dev/null +++ b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/reflect-config.json @@ -0,0 +1,23 @@ +[ + { + "name": "fortunes", + "allPublicMethods": true, + "allDeclaredFields": true, + "allDeclaredMethods": true, + "allDeclaredConstructors": true + }, + { + "name": "fortunes$Template", + "allPublicMethods": true, + "allDeclaredFields": true, + "allDeclaredMethods": true, + "allDeclaredConstructors": true + }, + { + "name": "fortunes$PlainText", + "allPublicMethods": true, + "allDeclaredFields": true, + "allDeclaredMethods": true, + "allDeclaredConstructors": true + } +] diff --git a/frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.pebble.html b/frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.pebble.html deleted file mode 100644 index 1a74dd9800c..00000000000 --- a/frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.pebble.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - Fortunes - - - - - - - - {% for fortune in fortunes %} - - - - - {% endfor %} -
idmessage
{{ fortune.id }}{{ fortune.message }}
- - diff --git a/frameworks/Kotlin/hexagon/core_async/build.gradle b/frameworks/Kotlin/hexagon/core_async/build.gradle new file mode 100644 index 00000000000..0a33387738e --- /dev/null +++ b/frameworks/Kotlin/hexagon/core_async/build.gradle @@ -0,0 +1,32 @@ + +plugins { + id("nu.studer.rocker") version("3.0.4") +} + +dependencies { + api(project(":model")) + api("com.hexagonkt:http_server_async:$hexagonVersion") + api("com.hexagonkt:templates_rocker:$hexagonVersion") + api("com.hexagonkt:logging_slf4j_jul:$hexagonVersion") + api("com.hexagonkt:serialization_jackson_json:$hexagonVersion") + api("org.cache2k:cache2k-core:$cache2kVersion") +} + +tasks.register("minimizeTemplate") { + doLast { + File template = file("$buildDir/resources/main/fortunes.rocker.html") + List lines = template.readLines().collect { it.trim() } + template.write(lines.join("")) + } +} + +jar.dependsOn("minimizeTemplate") + +rocker { + configurations { + create("main") { + templateDir.set(file("src/main/resources")) + optimize.set(true) + } + } +} diff --git a/frameworks/Kotlin/hexagon/core_async/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/core_async/src/main/kotlin/Benchmark.kt new file mode 100644 index 00000000000..2bda28da73e --- /dev/null +++ b/frameworks/Kotlin/hexagon/core_async/src/main/kotlin/Benchmark.kt @@ -0,0 +1,28 @@ +package com.hexagonkt.async + +import com.hexagonkt.Settings +import com.hexagonkt.http.server.async.HttpServer +import com.hexagonkt.http.server.async.HttpServerPort +import com.hexagonkt.http.server.async.HttpServerSettings +import com.hexagonkt.async.store.BenchmarkStore +import com.hexagonkt.templates.TemplatePort +import java.net.InetAddress +import java.net.URL + +class Benchmark( + private val engine: HttpServerPort, + private val store: BenchmarkStore, + private val template: TemplatePort, + private val templateUrl: URL, + private val settings: Settings = Settings(), +) { + val server: HttpServer by lazy { + val controller = Controller(settings, store, template, templateUrl) + val serverSettings = HttpServerSettings( + bindAddress = InetAddress.getByName(settings.bindAddress), + bindPort = settings.bindPort, + ) + + HttpServer(engine, controller.path, serverSettings) + } +} diff --git a/frameworks/Kotlin/hexagon/core_async/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/core_async/src/main/kotlin/Controller.kt new file mode 100644 index 00000000000..683d39f4ffa --- /dev/null +++ b/frameworks/Kotlin/hexagon/core_async/src/main/kotlin/Controller.kt @@ -0,0 +1,133 @@ +package com.hexagonkt.async + +import com.hexagonkt.Settings +import com.hexagonkt.core.fieldsMapOf +import com.hexagonkt.core.media.APPLICATION_JSON +import com.hexagonkt.core.media.TEXT_HTML +import com.hexagonkt.core.media.TEXT_PLAIN +import com.hexagonkt.handlers.async.done +import com.hexagonkt.http.model.ContentType +import com.hexagonkt.http.model.Header +import com.hexagonkt.http.model.Headers +import com.hexagonkt.http.server.async.callbacks.DateCallback +import com.hexagonkt.http.handlers.async.HttpContext +import com.hexagonkt.http.handlers.async.PathHandler +import com.hexagonkt.http.handlers.async.path +import com.hexagonkt.model.* +import com.hexagonkt.serialization.jackson.json.Json +import com.hexagonkt.serialization.serialize +import com.hexagonkt.async.store.BenchmarkStore +import com.hexagonkt.templates.TemplatePort +import java.net.URL +import java.util.concurrent.CompletableFuture +import java.util.concurrent.ThreadLocalRandom +import kotlin.text.Charsets.UTF_8 + +class Controller( + settings: Settings, + store: BenchmarkStore, + templateEngine: TemplatePort, + templateUrl: URL, +) { + private val queriesParam: String = settings.queriesParam + private val cachedQueriesParam: String = settings.cachedQueriesParam + private val worldRows: Int = settings.worldRows + private val textMessage: String = settings.textMessage + + private val plain: ContentType = ContentType(TEXT_PLAIN) + private val json: ContentType = ContentType(APPLICATION_JSON) + private val html: ContentType = ContentType(TEXT_HTML, charset = UTF_8) + + private val headers = Headers(Header("server", "Hexagon")) + + val path: PathHandler by lazy { + path { + on("*") { send(headers = headers).done() } + on("*", DateCallback()) + + get("/plaintext") { ok(textMessage, contentType = plain).done() } + get("/json") { ok(Message(textMessage).toJson(), contentType = json).done() } + get("/fortunes") { listFortunes(store, templateUrl, templateEngine) } + get("/db") { dbQuery(store) } + get("/query") { getWorlds(store) } + get("/cached-queries") { getCachedWorlds(store) } + get("/update") { updateWorlds(store) } + } + } + + private fun Message.toJson(): String = + toMap().serialize(Json.raw) + + private fun HttpContext.listFortunes( + store: BenchmarkStore, templateUrl: URL, templateAdapter: TemplatePort + ): CompletableFuture = + store + .findAllFortunes() + .thenApply { it + Fortune(0, "Additional fortune added at request time.") } + .thenApply { fortunes -> fortunes.sortedBy { it.message } } + .thenApply { sortedFortunes -> mapOf("fortunes" to sortedFortunes) } + .thenApply { context -> templateAdapter.render(templateUrl, context) } + .thenApply { body -> ok(body, contentType = html) } + + private fun HttpContext.dbQuery(store: BenchmarkStore): CompletableFuture { + val ids = listOf(randomWorld()) + return store.findWorlds(ids) + .thenApply { worlds -> worlds.first().toMap()} + .thenApply { world -> sendJson(world) } + } + + private fun HttpContext.getWorlds(store: BenchmarkStore): CompletableFuture { + val worldsCount = getWorldsCount(queriesParam) + val ids = (1..worldsCount).map { randomWorld() } + return store.findWorlds(ids) + .thenApply { worlds -> worlds.map { it.toMap() } } + .thenApply { worlds -> sendJson(worlds) } + } + + private fun HttpContext.getCachedWorlds(store: BenchmarkStore): CompletableFuture { + val worldsCount = getWorldsCount(cachedQueriesParam) + val ids = (1..worldsCount).map { randomWorld() } + val worlds = store.findCachedWorlds(ids).map { it.toMap() } + + return sendJson(worlds).done() + } + + private fun HttpContext.updateWorlds(store: BenchmarkStore): CompletableFuture { + val worldsCount = getWorldsCount(queriesParam) + val worlds = (1..worldsCount).map { World(randomWorld(), randomWorld()) } + + return store.replaceWorlds(worlds) + .thenApply { sendJson(worlds.map { it.toMap() }) } + } + + private fun HttpContext.sendJson(body: Any): HttpContext = + ok(body.serialize(Json.raw), contentType = json) + + private fun HttpContext.getWorldsCount(parameter: String): Int = + request.queryParameters[parameter]?.string()?.toIntOrNull().let { + when { + it == null -> 1 + it < 1 -> 1 + it > 500 -> 500 + else -> it + } + } + + private fun randomWorld(): Int = + ThreadLocalRandom.current().nextInt(worldRows) + 1 + + private fun Message.toMap(): Map = + fieldsMapOf(Message::message to message) + + private fun World.toMap(): Map = + fieldsMapOf( + World::id to id, + World::randomNumber to randomNumber, + ) + + private fun CachedWorld.toMap(): Map = + fieldsMapOf( + CachedWorld::id to id, + CachedWorld::randomNumber to randomNumber, + ) +} diff --git a/frameworks/Kotlin/hexagon/core_async/src/main/kotlin/store/BenchmarkStore.kt b/frameworks/Kotlin/hexagon/core_async/src/main/kotlin/store/BenchmarkStore.kt new file mode 100644 index 00000000000..13f5aae7108 --- /dev/null +++ b/frameworks/Kotlin/hexagon/core_async/src/main/kotlin/store/BenchmarkStore.kt @@ -0,0 +1,34 @@ +package com.hexagonkt.async.store + +import com.hexagonkt.model.CachedWorld +import com.hexagonkt.model.Fortune +import com.hexagonkt.Settings +import com.hexagonkt.model.World +import org.cache2k.Cache +import org.cache2k.Cache2kBuilder +import java.util.concurrent.CompletableFuture + +abstract class BenchmarkStore(settings: Settings) { + + abstract fun findAllFortunes(): CompletableFuture> + abstract fun findWorlds(ids: List): CompletableFuture> + abstract fun replaceWorlds(worlds: List): CompletableFuture<*> + abstract fun initWorldsCache(cache: Cache) + abstract fun loadCachedWorld(id: Int): CachedWorld + abstract fun close() + + private val worldsCache: Cache by lazy { + object : Cache2kBuilder() {} + .eternal(true) + .disableMonitoring(true) + .disableStatistics(true) + .entryCapacity(settings.worldRows.toLong()) + .loader { id -> loadCachedWorld(id) } + .build() + .apply { initWorldsCache(this) } + } + + fun findCachedWorlds(ids: List): List { + return ids.mapNotNull { worldsCache.get(it) } + } +} diff --git a/frameworks/Kotlin/hexagon/core_async/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties b/frameworks/Kotlin/hexagon/core_async/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties new file mode 100644 index 00000000000..ee1c0199d95 --- /dev/null +++ b/frameworks/Kotlin/hexagon/core_async/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties @@ -0,0 +1,7 @@ +Args= \ + -H:IncludeResources=.*\\.(html|class) \ + --enable-preview \ + --static \ + --initialize-at-build-time=org.slf4j.jul.JDK14LoggerAdapter \ + --initialize-at-build-time=org.slf4j.jul.JDK14LoggerAdapter$1 \ + --initialize-at-build-time=org.slf4j.LoggerFactory diff --git a/frameworks/Kotlin/hexagon/core_async/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/reflect-config.json b/frameworks/Kotlin/hexagon/core_async/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/reflect-config.json new file mode 100644 index 00000000000..11815306be2 --- /dev/null +++ b/frameworks/Kotlin/hexagon/core_async/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/reflect-config.json @@ -0,0 +1,23 @@ +[ + { + "name": "fortunes", + "allPublicMethods": true, + "allDeclaredFields": true, + "allDeclaredMethods": true, + "allDeclaredConstructors": true + }, + { + "name": "fortunes$Template", + "allPublicMethods": true, + "allDeclaredFields": true, + "allDeclaredMethods": true, + "allDeclaredConstructors": true + }, + { + "name": "fortunes$PlainText", + "allPublicMethods": true, + "allDeclaredFields": true, + "allDeclaredMethods": true, + "allDeclaredConstructors": true + } +] diff --git a/frameworks/Kotlin/hexagon/core_async/src/main/resources/fortunes.rocker.html b/frameworks/Kotlin/hexagon/core_async/src/main/resources/fortunes.rocker.html new file mode 100644 index 00000000000..c9a9d4037e5 --- /dev/null +++ b/frameworks/Kotlin/hexagon/core_async/src/main/resources/fortunes.rocker.html @@ -0,0 +1,24 @@ +@import java.util.* +@import com.hexagonkt.model.Fortune +@args(Map context) + + + + + Fortunes + + + + + + + + @for ((fortune) : (Collection)context.get("fortunes")) { + + + + + } +
idmessage
@fortune.getId()@fortune.getMessage()
+ + diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar index ccebba7710deaf9f98673a68957ea02138b60d0a..c1962a79e29d3e0ab67b14947c167a862655af9b 100644 GIT binary patch delta 8979 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 F{TFmrHLU;u delta 8469 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"BENCHMARK_ENV")?.lowercase() + maxSize = 8 + if (environment == "citrine") Jvm.cpuCount else Jvm.cpuCount * 2 + } + } + + private val dataSource: SqlClient by lazy { PgPool.pool(vertx(), connectOptions, poolOptions) } + + override fun findAllFortunes(): CompletableFuture> = + dataSource.preparedQuery(SELECT_ALL_FORTUNES) + .execute() + .map { rowSet -> + rowSet.map { row -> Fortune(row.getInteger(0), row.getString(1)) } + } + .toCompletionStage() + .toCompletableFuture() + + override fun findWorlds(ids: List): CompletableFuture> { + val futures = ids.map { findWorld(it, dataSource) } + return all(futures).map { it.list() }.toCompletionStage().toCompletableFuture() + } + + override fun replaceWorlds(worlds: List): CompletableFuture<*> { + val futures = worlds.map { + val worldId = it.id + val newRandomNumber = it.randomNumber + dataSource + .preparedQuery(SELECT_WORLD) + .execute(Tuple.of(worldId)) + .flatMap { 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)) + } + } + return all(futures).toCompletionStage().toCompletableFuture() + } + + override fun initWorldsCache(cache: Cache) { + 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 = + client + .preparedQuery(SELECT_WORLD) + .execute(Tuple.of(id)) + .map { rowSet -> + val row = rowSet.iterator().next() + World(row.getInteger(0), row.getInteger(1)) + } +} From 745aabf430b2a95fee6352dbc815608743ecb624 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 7 Jun 2023 16:05:40 +0200 Subject: [PATCH 088/149] Add async and native support --- .../Kotlin/hexagon/benchmark_config.json | 69 +++++++++++++++++++ frameworks/Kotlin/hexagon/config.toml | 54 +++++++++++++++ .../hexagon-netty-async-pgclient.dockerfile | 23 +++++++ .../hexagon/hexagon-vertx-pgclient.dockerfile | 23 +++++++ .../src/main/kotlin/BenchmarkPgClientStore.kt | 2 +- .../src/main/kotlin/BenchmarkPgClientStore.kt | 2 +- .../src/main/kotlin/BenchmarkSqlStore.kt | 2 +- 7 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 frameworks/Kotlin/hexagon/hexagon-netty-async-pgclient.dockerfile create mode 100644 frameworks/Kotlin/hexagon/hexagon-vertx-pgclient.dockerfile diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index 4bcc8b23f66..d5134ade6c8 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -136,6 +136,75 @@ "notes": "http://hexagonkt.com", "versus": "netty" }, + "netty-native": { + "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 Native PostgreSQL", + "notes": "http://hexagonkt.com", + "versus": "netty" + }, + "netty-async-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 Async PgClient", + "notes": "http://hexagonkt.com", + "versus": "netty" + }, + "vertx-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": "Vertx", + "webserver": "None", + "os": "Linux", + "database_os": "Linux", + "display_name": "Hexagon Vertx PgClient", + "notes": "http://hexagonkt.com", + "versus": "vertx" + }, "tomcat": { "json_url": "/json", "db_url": "/db", diff --git a/frameworks/Kotlin/hexagon/config.toml b/frameworks/Kotlin/hexagon/config.toml index d51d0e8ccf6..baeb6ac78ad 100644 --- a/frameworks/Kotlin/hexagon/config.toml +++ b/frameworks/Kotlin/hexagon/config.toml @@ -73,6 +73,24 @@ platform = "Netty" webserver = "None" versus = "netty" +[netty-native] +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" + [nettyepoll] urls.plaintext = "/plaintext" urls.json = "/json" @@ -109,6 +127,24 @@ platform = "Netty" webserver = "None" versus = "netty" +[nettyepoll-async-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" @@ -126,3 +162,21 @@ orm = "Raw" platform = "Servlet" webserver = "Tomcat" versus = "servlet" + +[vertx-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 = "Vertx" +webserver = "None" +versus = "vertx" diff --git a/frameworks/Kotlin/hexagon/hexagon-netty-async-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-netty-async-pgclient.dockerfile new file mode 100644 index 00000000000..09845f263cb --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon-netty-async-pgclient.dockerfile @@ -0,0 +1,23 @@ +# +# BUILD +# +FROM docker.io/gradle:8.1.1-jdk17-alpine AS build +USER root +WORKDIR /hexagon + +ADD . . +RUN gradle --quiet classes +RUN gradle --quiet -x test installDist + +# +# RUNTIME +# +FROM docker.io/eclipse-temurin:17-jre-alpine +ARG PROJECT=hexagon_netty_async_pgclient + +ENV POSTGRESQL_DB_HOST tfb-database +ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA + +COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT + +ENTRYPOINT [ "/opt/hexagon_netty_async_pgclient/bin/hexagon_netty_async_pgclient" ] diff --git a/frameworks/Kotlin/hexagon/hexagon-vertx-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-vertx-pgclient.dockerfile new file mode 100644 index 00000000000..5b8ff2cd1b1 --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon-vertx-pgclient.dockerfile @@ -0,0 +1,23 @@ +# +# BUILD +# +FROM docker.io/gradle:8.1.1-jdk17-alpine AS build +USER root +WORKDIR /hexagon + +ADD . . +RUN gradle --quiet classes +RUN gradle --quiet -x test installDist + +# +# RUNTIME +# +FROM docker.io/eclipse-temurin:17-jre-alpine +ARG PROJECT=hexagon_vertx_pgclient + +ENV POSTGRESQL_DB_HOST tfb-database +ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA + +COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT + +ENTRYPOINT [ "/opt/hexagon_vertx_pgclient/bin/hexagon_vertx_pgclient" ] diff --git a/frameworks/Kotlin/hexagon/store_pgclient/src/main/kotlin/BenchmarkPgClientStore.kt b/frameworks/Kotlin/hexagon/store_pgclient/src/main/kotlin/BenchmarkPgClientStore.kt index 5cd13ccee0a..1fb9547353f 100644 --- a/frameworks/Kotlin/hexagon/store_pgclient/src/main/kotlin/BenchmarkPgClientStore.kt +++ b/frameworks/Kotlin/hexagon/store_pgclient/src/main/kotlin/BenchmarkPgClientStore.kt @@ -24,7 +24,7 @@ class BenchmarkPgClientStore( private val connectOptions: PgConnectOptions by lazy { PgConnectOptions().apply { - host = Jvm.systemSettingOrNull("${engine.uppercase()}_DB_HOST") ?: "localhost" + host = Jvm.systemSettingOrNull("${engine.uppercase()}_DB_HOST") ?: "tfb-database" database = settings.databaseName user = settings.databaseUsername password = settings.databasePassword diff --git a/frameworks/Kotlin/hexagon/store_pgclient_async/src/main/kotlin/BenchmarkPgClientStore.kt b/frameworks/Kotlin/hexagon/store_pgclient_async/src/main/kotlin/BenchmarkPgClientStore.kt index f7b0350bfe9..8266b3120e4 100644 --- a/frameworks/Kotlin/hexagon/store_pgclient_async/src/main/kotlin/BenchmarkPgClientStore.kt +++ b/frameworks/Kotlin/hexagon/store_pgclient_async/src/main/kotlin/BenchmarkPgClientStore.kt @@ -27,7 +27,7 @@ class BenchmarkPgClientStore( private val connectOptions: PgConnectOptions by lazy { PgConnectOptions().apply { - host = Jvm.systemSettingOrNull("${engine.uppercase()}_DB_HOST") ?: "localhost" + host = Jvm.systemSettingOrNull("${engine.uppercase()}_DB_HOST") ?: "tfb-database" database = settings.databaseName user = settings.databaseUsername password = settings.databasePassword diff --git a/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt b/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt index ea871ec1b13..501a4d9ce34 100644 --- a/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt +++ b/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt @@ -22,7 +22,7 @@ class BenchmarkSqlStore( } private val dataSource: HikariDataSource by lazy { - val dbHost = Jvm.systemSettingOrNull("${engine.uppercase()}_DB_HOST") ?: "localhost" + val dbHost = Jvm.systemSettingOrNull("${engine.uppercase()}_DB_HOST") ?: "tfb-database" val environment = Jvm.systemSettingOrNull(String::class, "BENCHMARK_ENV")?.lowercase() val poolSize = 8 + if (environment == "citrine") Jvm.cpuCount else Jvm.cpuCount * 2 val postgresqlSettings = listOf( From f54f8803eabf78bb55ac83e3a3582dff3fbf2306 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 7 Jun 2023 16:12:35 +0200 Subject: [PATCH 089/149] Add async and native support --- frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index 77cf13f6cbb..e35db7b9f68 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -7,7 +7,7 @@ WORKDIR /hexagon ADD . . RUN gradle --quiet classes -RUN gradle --quiet -x test +RUN gradle --quiet -x test war # # RUNTIME From 267c4b626513161721edfce382629d5c79ce7d83 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 16 Jun 2023 11:26:16 +0200 Subject: [PATCH 090/149] Replace Vert.x adapter by Netty Epoll Async adapter --- frameworks/Kotlin/hexagon/build.gradle | 6 ++--- ...xagon-nettyepoll-async-pgclient.dockerfile | 23 +++++++++++++++++++ .../build.gradle | 8 +++++++ .../src/main/kotlin/Benchmark.kt | 4 ++-- .../hexagon_vertx_pgclient/build.gradle | 9 -------- frameworks/Kotlin/hexagon/settings.gradle | 2 +- 6 files changed, 37 insertions(+), 15 deletions(-) create mode 100644 frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile create mode 100644 frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/build.gradle rename frameworks/Kotlin/hexagon/{hexagon_vertx_pgclient => hexagon_nettyepoll_async_pgclient}/src/main/kotlin/Benchmark.kt (89%) delete mode 100644 frameworks/Kotlin/hexagon/hexagon_vertx_pgclient/build.gradle diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 755096930bc..f4a2ad995c7 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,6 +1,6 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "1.8.21" apply false + id "org.jetbrains.kotlin.jvm" version "1.8.22" apply false id "org.graalvm.buildtools.native" version "0.9.22" apply false } @@ -9,13 +9,13 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.0.0-B1" + hexagonVersion = "3.0.0-B3" jettyVersion = "11.0.15" nettyVersion = "4.1.93.Final" hikariVersion = "5.0.1" postgresqlVersion = "42.6.0" - vertxVersion = "4.4.2" + vertxVersion = "4.4.3" cache2kVersion = "2.6.1.Final" applicationClass = "com.hexagonkt.BenchmarkKt" diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile new file mode 100644 index 00000000000..17234b76d4f --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile @@ -0,0 +1,23 @@ +# +# BUILD +# +FROM docker.io/gradle:8.1.1-jdk17-alpine AS build +USER root +WORKDIR /hexagon + +ADD . . +RUN gradle --quiet classes +RUN gradle --quiet -x test installDist + +# +# RUNTIME +# +FROM docker.io/eclipse-temurin:17-jre-alpine +ARG PROJECT=hexagon_nettyepoll_async_pgclient + +ENV POSTGRESQL_DB_HOST tfb-database +ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA + +COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT + +ENTRYPOINT [ "/opt/hexagon_vertx_pgclient/bin/hexagon_vertx_pgclient" ] diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/build.gradle b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/build.gradle new file mode 100644 index 00000000000..9fb1cc22c05 --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/build.gradle @@ -0,0 +1,8 @@ + +apply(from: "$gradleScripts/application.gradle") + +dependencies { + api(project(":store_pgclient_async")) + api("com.hexagonkt:http_server_netty_epoll_async:$hexagonVersion") + api("io.netty:netty-transport-native-epoll:$nettyVersion") +} diff --git a/frameworks/Kotlin/hexagon/hexagon_vertx_pgclient/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/src/main/kotlin/Benchmark.kt similarity index 89% rename from frameworks/Kotlin/hexagon/hexagon_vertx_pgclient/src/main/kotlin/Benchmark.kt rename to frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/src/main/kotlin/Benchmark.kt index 6b52be6d68f..1e40fa3ffaf 100644 --- a/frameworks/Kotlin/hexagon/hexagon_vertx_pgclient/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/src/main/kotlin/Benchmark.kt @@ -2,7 +2,7 @@ package com.hexagonkt import com.hexagonkt.async.Benchmark import com.hexagonkt.async.store.BenchmarkPgClientStore -import com.hexagonkt.http.server.vertx.VertxServerAdapter +import com.hexagonkt.http.server.netty.epoll.async.NettyEpollServerAdapter import com.hexagonkt.templates.rocker.RockerAdapter import io.netty.util.ResourceLeakDetector import io.netty.util.ResourceLeakDetector.Level.DISABLED @@ -26,7 +26,7 @@ fun main() { val store = BenchmarkPgClientStore("postgresql") val templateEngine = RockerAdapter() val templateUrl = URL("classpath:fortunes.rocker.html") - val engine = VertxServerAdapter(preferNativeTransport = true) + val engine = NettyEpollServerAdapter(bossGroupThreads = 48) val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) benchmark.server.start() diff --git a/frameworks/Kotlin/hexagon/hexagon_vertx_pgclient/build.gradle b/frameworks/Kotlin/hexagon/hexagon_vertx_pgclient/build.gradle deleted file mode 100644 index 2d5cdaf23d7..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon_vertx_pgclient/build.gradle +++ /dev/null @@ -1,9 +0,0 @@ - -apply(from: "$gradleScripts/application.gradle") - -dependencies { - api(project(":store_pgclient_async")) - api("com.hexagonkt:http_server_vertx_async:$hexagonVersion") - api("io.vertx:vertx-io_uring-incubator:4.4.2") - api("io.netty:netty-transport-native-epoll:4.1.93.Final") -} diff --git a/frameworks/Kotlin/hexagon/settings.gradle b/frameworks/Kotlin/hexagon/settings.gradle index 7b6af470769..cf4ad98fdac 100644 --- a/frameworks/Kotlin/hexagon/settings.gradle +++ b/frameworks/Kotlin/hexagon/settings.gradle @@ -12,7 +12,7 @@ include( "hexagon_netty_postgresql", "hexagon_netty_async_pgclient", "hexagon_nettyepoll_pgclient", + "hexagon_nettyepoll_async_pgclient", "hexagon_nettyepoll_postgresql", - "hexagon_vertx_pgclient", "hexagon_tomcat_postgresql", ) From 9c2385b3785dee56e4843d771e3d52fbdd6e6678 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 16 Jun 2023 12:31:53 +0200 Subject: [PATCH 091/149] Replace Vert.x adapter by Netty Epoll Async adapter --- .../Kotlin/hexagon/benchmark_config.json | 6 ++--- frameworks/Kotlin/hexagon/config.toml | 6 ++--- .../hexagon/hexagon-vertx-pgclient.dockerfile | 23 ------------------- 3 files changed, 6 insertions(+), 29 deletions(-) delete mode 100644 frameworks/Kotlin/hexagon/hexagon-vertx-pgclient.dockerfile diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index d5134ade6c8..d9f60d20b6f 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -182,7 +182,7 @@ "notes": "http://hexagonkt.com", "versus": "netty" }, - "vertx-pgclient": { + "nettyepoll-async-pgclient": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -197,13 +197,13 @@ "framework": "Hexagon", "language": "Kotlin", "orm": "Raw", - "platform": "Vertx", + "platform": "Netty", "webserver": "None", "os": "Linux", "database_os": "Linux", "display_name": "Hexagon Vertx PgClient", "notes": "http://hexagonkt.com", - "versus": "vertx" + "versus": "netty" }, "tomcat": { "json_url": "/json", diff --git a/frameworks/Kotlin/hexagon/config.toml b/frameworks/Kotlin/hexagon/config.toml index baeb6ac78ad..d30e5353e5a 100644 --- a/frameworks/Kotlin/hexagon/config.toml +++ b/frameworks/Kotlin/hexagon/config.toml @@ -163,7 +163,7 @@ platform = "Servlet" webserver = "Tomcat" versus = "servlet" -[vertx-pgclient] +[nettyepoll-async-pgclient] urls.plaintext = "/plaintext" urls.json = "/json" urls.db = "/db" @@ -177,6 +177,6 @@ database = "postgres" database_os = "Linux" os = "Linux" orm = "Raw" -platform = "Vertx" +platform = "Netty" webserver = "None" -versus = "vertx" +versus = "netty" diff --git a/frameworks/Kotlin/hexagon/hexagon-vertx-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-vertx-pgclient.dockerfile deleted file mode 100644 index 5b8ff2cd1b1..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon-vertx-pgclient.dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# -# BUILD -# -FROM docker.io/gradle:8.1.1-jdk17-alpine AS build -USER root -WORKDIR /hexagon - -ADD . . -RUN gradle --quiet classes -RUN gradle --quiet -x test installDist - -# -# RUNTIME -# -FROM docker.io/eclipse-temurin:17-jre-alpine -ARG PROJECT=hexagon_vertx_pgclient - -ENV POSTGRESQL_DB_HOST tfb-database -ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA - -COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT - -ENTRYPOINT [ "/opt/hexagon_vertx_pgclient/bin/hexagon_vertx_pgclient" ] From 10081f798389d199144618e4446b731d5a80fdee Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 16 Jun 2023 14:20:51 +0200 Subject: [PATCH 092/149] Replace Vert.x adapter by Netty Epoll Async adapter --- .../Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile index 17234b76d4f..7e4c80d6cd4 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile @@ -20,4 +20,4 @@ ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT -ENTRYPOINT [ "/opt/hexagon_vertx_pgclient/bin/hexagon_vertx_pgclient" ] +ENTRYPOINT [ "/opt/hexagon_nettyepoll_async_pgclient/bin/hexagon_nettyepoll_async_pgclient" ] From 10b312c8765639fd0343ad45da4b89276953fd15 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 16 Jun 2023 16:18:31 +0200 Subject: [PATCH 093/149] Replace Vert.x adapter by Netty Epoll Async adapter --- .../hexagon/hexagon_nettyepoll_async_pgclient/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/build.gradle b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/build.gradle index 9fb1cc22c05..148de98b406 100644 --- a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/build.gradle +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/build.gradle @@ -4,5 +4,5 @@ apply(from: "$gradleScripts/application.gradle") dependencies { api(project(":store_pgclient_async")) api("com.hexagonkt:http_server_netty_epoll_async:$hexagonVersion") - api("io.netty:netty-transport-native-epoll:$nettyVersion") + api("io.netty:netty-transport-native-epoll:$nettyVersion:linux-x86_64") } From efc7321d5a7f065bb306c01588747bf251a6b44d Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sat, 17 Jun 2023 12:58:42 +0200 Subject: [PATCH 094/149] Replace Vert.x adapter by Netty Epoll Async adapter --- .../Kotlin/hexagon/benchmark_config.json | 18 +++++++-------- frameworks/Kotlin/hexagon/config.toml | 18 --------------- ...xagon-nettyepoll-async-pgclient.dockerfile | 2 +- .../hexagon/hexagon-vertx-pgclient.dockerfile | 23 ------------------- .../src/main/kotlin/Benchmark.kt | 8 ------- 5 files changed, 9 insertions(+), 60 deletions(-) delete mode 100644 frameworks/Kotlin/hexagon/hexagon-vertx-pgclient.dockerfile diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index d5134ade6c8..90db8bffd93 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -136,14 +136,12 @@ "notes": "http://hexagonkt.com", "versus": "netty" }, - "netty-native": { - "json_url": "/json", + "nettyepoll-async-pgclient": { "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", @@ -155,11 +153,11 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Netty Native PostgreSQL", + "display_name": "Hexagon Netty Epoll PgClient", "notes": "http://hexagonkt.com", "versus": "netty" }, - "netty-async-pgclient": { + "netty-native": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -178,11 +176,11 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Netty Async PgClient", + "display_name": "Hexagon Netty Native PostgreSQL", "notes": "http://hexagonkt.com", "versus": "netty" }, - "vertx-pgclient": { + "netty-async-pgclient": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -197,13 +195,13 @@ "framework": "Hexagon", "language": "Kotlin", "orm": "Raw", - "platform": "Vertx", + "platform": "Netty", "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Vertx PgClient", + "display_name": "Hexagon Netty Async PgClient", "notes": "http://hexagonkt.com", - "versus": "vertx" + "versus": "netty" }, "tomcat": { "json_url": "/json", diff --git a/frameworks/Kotlin/hexagon/config.toml b/frameworks/Kotlin/hexagon/config.toml index baeb6ac78ad..488f052bb61 100644 --- a/frameworks/Kotlin/hexagon/config.toml +++ b/frameworks/Kotlin/hexagon/config.toml @@ -162,21 +162,3 @@ orm = "Raw" platform = "Servlet" webserver = "Tomcat" versus = "servlet" - -[vertx-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 = "Vertx" -webserver = "None" -versus = "vertx" diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile index 17234b76d4f..7e4c80d6cd4 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile @@ -20,4 +20,4 @@ ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT -ENTRYPOINT [ "/opt/hexagon_vertx_pgclient/bin/hexagon_vertx_pgclient" ] +ENTRYPOINT [ "/opt/hexagon_nettyepoll_async_pgclient/bin/hexagon_nettyepoll_async_pgclient" ] diff --git a/frameworks/Kotlin/hexagon/hexagon-vertx-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-vertx-pgclient.dockerfile deleted file mode 100644 index 5b8ff2cd1b1..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon-vertx-pgclient.dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# -# BUILD -# -FROM docker.io/gradle:8.1.1-jdk17-alpine AS build -USER root -WORKDIR /hexagon - -ADD . . -RUN gradle --quiet classes -RUN gradle --quiet -x test installDist - -# -# RUNTIME -# -FROM docker.io/eclipse-temurin:17-jre-alpine -ARG PROJECT=hexagon_vertx_pgclient - -ENV POSTGRESQL_DB_HOST tfb-database -ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA - -COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT - -ENTRYPOINT [ "/opt/hexagon_vertx_pgclient/bin/hexagon_vertx_pgclient" ] diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/src/main/kotlin/Benchmark.kt index 1e40fa3ffaf..0b21842bc8f 100644 --- a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/src/main/kotlin/Benchmark.kt @@ -11,14 +11,6 @@ import java.net.URL fun main() { ResourceLeakDetector.setLevel(DISABLED) - System.setProperty("vertx.disableMetrics", "true") - System.setProperty("vertx.disableH2c", "true") - System.setProperty("vertx.disableWebsockets", "true") - System.setProperty("vertx.flashPolicyHandler", "false") - System.setProperty("vertx.threadChecks", "false") - System.setProperty("vertx.disableContextTimings", "true") - System.setProperty("vertx.disableTCCL", "true") - System.setProperty("vertx.disableHttpHeadersValidation", "true") System.setProperty("io.netty.buffer.checkBounds", "false") System.setProperty("io.netty.buffer.checkAccessible", "false") From 3b053f41613114925dcb8973536360aa52e6fcfb Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sat, 17 Jun 2023 22:16:45 +0200 Subject: [PATCH 095/149] Add Jasync store --- .../Kotlin/hexagon/benchmark_config.json | 23 ++++ frameworks/Kotlin/hexagon/build.gradle | 1 + frameworks/Kotlin/hexagon/config.toml | 18 +++ ...hexagon-nettyepoll-async-jasync.dockerfile | 23 ++++ .../build.gradle | 8 ++ .../src/main/kotlin/Benchmark.kt | 25 +++++ .../src/main/kotlin/Benchmark.kt | 8 ++ frameworks/Kotlin/hexagon/settings.gradle | 2 + .../Kotlin/hexagon/store_jasync/build.gradle | 5 + .../src/main/kotlin/BenchmarkJasyncStore.kt | 106 ++++++++++++++++++ 10 files changed, 219 insertions(+) create mode 100644 frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-jasync.dockerfile create mode 100644 frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_jasync/build.gradle create mode 100644 frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_jasync/src/main/kotlin/Benchmark.kt create mode 100644 frameworks/Kotlin/hexagon/store_jasync/build.gradle create mode 100644 frameworks/Kotlin/hexagon/store_jasync/src/main/kotlin/BenchmarkJasyncStore.kt diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index 90db8bffd93..e16837acbe8 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -180,6 +180,29 @@ "notes": "http://hexagonkt.com", "versus": "netty" }, + "netty-async-jasync": { + "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 Async Jasync", + "notes": "http://hexagonkt.com", + "versus": "netty" + }, "netty-async-pgclient": { "json_url": "/json", "db_url": "/db", diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index f4a2ad995c7..47101f72dbf 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -16,6 +16,7 @@ ext { hikariVersion = "5.0.1" postgresqlVersion = "42.6.0" vertxVersion = "4.4.3" + jasyncVersion = "2.2.0" cache2kVersion = "2.6.1.Final" applicationClass = "com.hexagonkt.BenchmarkKt" diff --git a/frameworks/Kotlin/hexagon/config.toml b/frameworks/Kotlin/hexagon/config.toml index 488f052bb61..be5cfb36a91 100644 --- a/frameworks/Kotlin/hexagon/config.toml +++ b/frameworks/Kotlin/hexagon/config.toml @@ -145,6 +145,24 @@ platform = "Netty" webserver = "None" versus = "netty" +[nettyepoll-async-jasync] +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" diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-jasync.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-jasync.dockerfile new file mode 100644 index 00000000000..d35474e1b0b --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-jasync.dockerfile @@ -0,0 +1,23 @@ +# +# BUILD +# +FROM docker.io/gradle:8.1.1-jdk17-alpine AS build +USER root +WORKDIR /hexagon + +ADD . . +RUN gradle --quiet classes +RUN gradle --quiet -x test installDist + +# +# RUNTIME +# +FROM docker.io/eclipse-temurin:17-jre-alpine +ARG PROJECT=hexagon_nettyepoll_async_jasync + +ENV POSTGRESQL_DB_HOST tfb-database +ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA + +COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT + +ENTRYPOINT [ "/opt/hexagon_nettyepoll_async_jasync/bin/hexagon_nettyepoll_async_jasync" ] diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_jasync/build.gradle b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_jasync/build.gradle new file mode 100644 index 00000000000..62804c2f8c4 --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_jasync/build.gradle @@ -0,0 +1,8 @@ + +apply(from: "$gradleScripts/application.gradle") + +dependencies { + api(project(":store_jasync")) + api("com.hexagonkt:http_server_netty_epoll_async:$hexagonVersion") + api("io.netty:netty-transport-native-epoll:$nettyVersion:linux-x86_64") +} diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_jasync/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_jasync/src/main/kotlin/Benchmark.kt new file mode 100644 index 00000000000..eee45899d05 --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_jasync/src/main/kotlin/Benchmark.kt @@ -0,0 +1,25 @@ +package com.hexagonkt + +import com.hexagonkt.async.Benchmark +import com.hexagonkt.async.store.BenchmarkJasyncStore +import com.hexagonkt.http.server.netty.epoll.async.NettyEpollServerAdapter +import com.hexagonkt.templates.rocker.RockerAdapter +import io.netty.util.ResourceLeakDetector +import io.netty.util.ResourceLeakDetector.Level.DISABLED +import java.net.URL + +fun main() { + ResourceLeakDetector.setLevel(DISABLED) + + System.setProperty("io.netty.buffer.checkBounds", "false") + System.setProperty("io.netty.buffer.checkAccessible", "false") + + val settings = Settings() + val store = BenchmarkJasyncStore("postgresql") + val templateEngine = RockerAdapter() + val templateUrl = URL("classpath:fortunes.rocker.html") + val engine = NettyEpollServerAdapter(bossGroupThreads = 48) + + val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) + benchmark.server.start() +} diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/src/main/kotlin/Benchmark.kt index 0b21842bc8f..1e40fa3ffaf 100644 --- a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/src/main/kotlin/Benchmark.kt @@ -11,6 +11,14 @@ import java.net.URL fun main() { ResourceLeakDetector.setLevel(DISABLED) + System.setProperty("vertx.disableMetrics", "true") + System.setProperty("vertx.disableH2c", "true") + System.setProperty("vertx.disableWebsockets", "true") + System.setProperty("vertx.flashPolicyHandler", "false") + System.setProperty("vertx.threadChecks", "false") + System.setProperty("vertx.disableContextTimings", "true") + System.setProperty("vertx.disableTCCL", "true") + System.setProperty("vertx.disableHttpHeadersValidation", "true") System.setProperty("io.netty.buffer.checkBounds", "false") System.setProperty("io.netty.buffer.checkAccessible", "false") diff --git a/frameworks/Kotlin/hexagon/settings.gradle b/frameworks/Kotlin/hexagon/settings.gradle index cf4ad98fdac..d07b35f2779 100644 --- a/frameworks/Kotlin/hexagon/settings.gradle +++ b/frameworks/Kotlin/hexagon/settings.gradle @@ -3,6 +3,7 @@ include( "model", "core", "core_async", + "store_jasync", "store_pgclient", "store_pgclient_async", "store_sql", @@ -12,6 +13,7 @@ include( "hexagon_netty_postgresql", "hexagon_netty_async_pgclient", "hexagon_nettyepoll_pgclient", + "hexagon_nettyepoll_async_jasync", "hexagon_nettyepoll_async_pgclient", "hexagon_nettyepoll_postgresql", "hexagon_tomcat_postgresql", diff --git a/frameworks/Kotlin/hexagon/store_jasync/build.gradle b/frameworks/Kotlin/hexagon/store_jasync/build.gradle new file mode 100644 index 00000000000..5ead678dd16 --- /dev/null +++ b/frameworks/Kotlin/hexagon/store_jasync/build.gradle @@ -0,0 +1,5 @@ + +dependencies { + api(project(":core_async")) + implementation("com.github.jasync-sql:jasync-postgresql:$jasyncVersion") +} diff --git a/frameworks/Kotlin/hexagon/store_jasync/src/main/kotlin/BenchmarkJasyncStore.kt b/frameworks/Kotlin/hexagon/store_jasync/src/main/kotlin/BenchmarkJasyncStore.kt new file mode 100644 index 00000000000..0f5702c5e84 --- /dev/null +++ b/frameworks/Kotlin/hexagon/store_jasync/src/main/kotlin/BenchmarkJasyncStore.kt @@ -0,0 +1,106 @@ +package com.hexagonkt.async.store + +import com.github.jasync.sql.db.ConnectionPoolConfigurationBuilder +import com.github.jasync.sql.db.pool.ConnectionPool +import com.github.jasync.sql.db.postgresql.PostgreSQLConnection +import com.github.jasync.sql.db.postgresql.PostgreSQLConnectionBuilder +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 org.cache2k.Cache +import java.util.concurrent.CompletableFuture +import java.util.concurrent.CompletableFuture.allOf + +class BenchmarkJasyncStore( + 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 dataSource: ConnectionPool by lazy { + ConnectionPoolConfigurationBuilder().let { + val environment = Jvm.systemSettingOrNull("BENCHMARK_ENV")?.lowercase() + val cpuCount = Jvm.cpuCount + + it.maxActiveConnections = 8 + if (environment == "citrine") cpuCount else cpuCount * 2 + it.host = Jvm.systemSettingOrNull("${engine.uppercase()}_DB_HOST") ?: "tfb-database" + it.database = settings.databaseName + it.username = settings.databaseUsername + it.password = settings.databasePassword + + PostgreSQLConnectionBuilder.createConnectionPool(it.build()) + } + } + + override fun findAllFortunes(): CompletableFuture> = + dataSource.sendPreparedStatement(SELECT_ALL_FORTUNES) + .thenApply { result -> + val rowSet = result.rows + rowSet.map { row -> + val id = row.getInt(0) ?: error("") + val message = row.getString(1) ?: error("") + Fortune(id, message) + } + } + + override fun findWorlds(ids: List): CompletableFuture> { + val futures = ids.map { findWorld(it, dataSource) }.toTypedArray() + return allOf(*futures).thenApply { futures.map { f -> f.get() ?: error("") } } + } + + override fun replaceWorlds(worlds: List): CompletableFuture<*> { + val futures = worlds.map { + val worldId = it.id + val newRandomNumber = it.randomNumber + dataSource + .sendPreparedStatement(SELECT_WORLD, listOf(worldId)) + .thenApply { rowSet -> + val row = rowSet.rows.iterator().next() + row.getInt(1) // Read 'randomNumber' to comply with Test type 5, point 6 + dataSource + .sendPreparedStatement(UPDATE_WORLD, listOf(newRandomNumber, worldId)) + } + }.toTypedArray() + + return allOf(*futures).thenApply { futures.map { f -> f.get() ?: error("") } } + } + + override fun initWorldsCache(cache: Cache) { + dataSource + .sendPreparedStatement("select * from world") + .thenApply { rowSet -> + rowSet.rows.map { row -> + val id = row.getInt(0) ?: error("") + val randomNumber = row.getInt(1) ?: error("") + cache.put(id, CachedWorld(id, randomNumber)) + } + } + .get() + } + + override fun loadCachedWorld(id: Int): CachedWorld = + findWorld(id, dataSource) + .thenApply { world -> CachedWorld(world.id, world.randomNumber) } + .get() + + override fun close() { + dataSource.disconnect().get() + } + + private fun findWorld(id: Int, client: ConnectionPool<*>): CompletableFuture = + client + .sendPreparedStatement(SELECT_WORLD, listOf(id)) + .thenApply { rowSet -> + val row = rowSet.rows.iterator().next() + val id1 = row.getInt(0) ?: error("") + val randomNumber = row.getInt(1) ?: error("") + World(id1, randomNumber) + } +} From 3c6475953104029274b29ae9a91ee0fa8cf5e8ce Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sun, 18 Jun 2023 08:52:52 +0200 Subject: [PATCH 096/149] Add Jasync store --- frameworks/Kotlin/hexagon/benchmark_config.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index e16837acbe8..4874edffd24 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -153,11 +153,11 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Netty Epoll PgClient", + "display_name": "Hexagon Netty Epoll Async PgClient", "notes": "http://hexagonkt.com", "versus": "netty" }, - "netty-native": { + "nettyepoll-async-jasync": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -176,11 +176,11 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Netty Native PostgreSQL", + "display_name": "Hexagon Netty Epoll Async Jasync", "notes": "http://hexagonkt.com", "versus": "netty" }, - "netty-async-jasync": { + "netty-native": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -199,7 +199,7 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Netty Async Jasync", + "display_name": "Hexagon Netty Native PostgreSQL", "notes": "http://hexagonkt.com", "versus": "netty" }, From 4c921b4bdf41ca9efb676f2588b8f496e5c4382f Mon Sep 17 00:00:00 2001 From: jaguililla Date: Mon, 10 Jul 2023 19:39:26 +0200 Subject: [PATCH 097/149] Update --- frameworks/Kotlin/hexagon/build.gradle | 10 +- .../hexagon-jettyloom-pgclient.dockerfile | 2 +- .../hexagon/hexagon-jettyloom.dockerfile | 2 +- .../hexagon-netty-async-pgclient.dockerfile | 2 +- .../Kotlin/hexagon/hexagon-netty.dockerfile | 2 +- ...hexagon-nettyepoll-async-jasync.dockerfile | 10 +- .../hexagon/hexagon-nettyepoll.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon.dockerfile | 2 +- .../build.gradle | 8 -- .../src/main/kotlin/Benchmark.kt | 25 ----- .../Kotlin/hexagon/store_jasync/build.gradle | 5 - .../src/main/kotlin/BenchmarkJasyncStore.kt | 106 ------------------ 12 files changed, 12 insertions(+), 164 deletions(-) delete mode 100644 frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_jasync/build.gradle delete mode 100644 frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_jasync/src/main/kotlin/Benchmark.kt delete mode 100644 frameworks/Kotlin/hexagon/store_jasync/build.gradle delete mode 100644 frameworks/Kotlin/hexagon/store_jasync/src/main/kotlin/BenchmarkJasyncStore.kt diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index f4a2ad995c7..fecbf1174e6 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,7 +1,7 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "1.8.22" apply false - id "org.graalvm.buildtools.native" version "0.9.22" apply false + id "org.jetbrains.kotlin.jvm" version "1.9.0" apply false + id "org.graalvm.buildtools.native" version "0.9.23" apply false } version = "1.0.0" @@ -9,13 +9,13 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.0.0-B3" + hexagonVersion = "3.0.0-B8" jettyVersion = "11.0.15" - nettyVersion = "4.1.93.Final" + nettyVersion = "4.1.94.Final" hikariVersion = "5.0.1" postgresqlVersion = "42.6.0" - vertxVersion = "4.4.3" + vertxVersion = "4.4.4" cache2kVersion = "2.6.1.Final" applicationClass = "com.hexagonkt.BenchmarkKt" diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile index 804555dae57..390ce706bc6 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.1.1-jdk17-alpine AS build +FROM docker.io/gradle:8.2-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile index 1d64e9246dd..97809e8cc05 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.1.1-jdk17-alpine AS build +FROM docker.io/gradle:8.2-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-netty-async-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-netty-async-pgclient.dockerfile index 09845f263cb..ddb35d90de8 100644 --- a/frameworks/Kotlin/hexagon/hexagon-netty-async-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-netty-async-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.1.1-jdk17-alpine AS build +FROM docker.io/gradle:8.2-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile index 18fce97d813..16b71649263 100644 --- a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.1.1-jdk17-alpine AS build +FROM docker.io/gradle:8.2-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-jasync.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-jasync.dockerfile index 9307f4120ab..aae9e180c7d 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-jasync.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-jasync.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.1.1-jdk17-alpine AS build +FROM docker.io/gradle:8.2-jdk17-alpine AS build USER root WORKDIR /hexagon @@ -13,19 +13,11 @@ RUN gradle --quiet -x test installDist # RUNTIME # FROM docker.io/eclipse-temurin:17-jre-alpine -<<<<<<<< HEAD:frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-jasync.dockerfile -ARG PROJECT=hexagon_nettyepoll_async_jasync -======== ARG PROJECT=hexagon_nettyepoll_async_pgclient ->>>>>>>> 1d0e4006abc9d1d1cfee1f3f2e5bdbc9fbab8f11:frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile ENV POSTGRESQL_DB_HOST tfb-database ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT -<<<<<<<< HEAD:frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-jasync.dockerfile -ENTRYPOINT [ "/opt/hexagon_nettyepoll_async_jasync/bin/hexagon_nettyepoll_async_jasync" ] -======== ENTRYPOINT [ "/opt/hexagon_nettyepoll_async_pgclient/bin/hexagon_nettyepoll_async_pgclient" ] ->>>>>>>> 1d0e4006abc9d1d1cfee1f3f2e5bdbc9fbab8f11:frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile index c8a5592b67e..9b083b9683d 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.1.1-jdk17-alpine AS build +FROM docker.io/gradle:8.2-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index 6bc878580ab..2cf68db7f9f 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.1.1-jdk17-alpine AS build +FROM docker.io/gradle:8.2-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_jasync/build.gradle b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_jasync/build.gradle deleted file mode 100644 index 62804c2f8c4..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_jasync/build.gradle +++ /dev/null @@ -1,8 +0,0 @@ - -apply(from: "$gradleScripts/application.gradle") - -dependencies { - api(project(":store_jasync")) - api("com.hexagonkt:http_server_netty_epoll_async:$hexagonVersion") - api("io.netty:netty-transport-native-epoll:$nettyVersion:linux-x86_64") -} diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_jasync/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_jasync/src/main/kotlin/Benchmark.kt deleted file mode 100644 index eee45899d05..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_jasync/src/main/kotlin/Benchmark.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.hexagonkt - -import com.hexagonkt.async.Benchmark -import com.hexagonkt.async.store.BenchmarkJasyncStore -import com.hexagonkt.http.server.netty.epoll.async.NettyEpollServerAdapter -import com.hexagonkt.templates.rocker.RockerAdapter -import io.netty.util.ResourceLeakDetector -import io.netty.util.ResourceLeakDetector.Level.DISABLED -import java.net.URL - -fun main() { - ResourceLeakDetector.setLevel(DISABLED) - - System.setProperty("io.netty.buffer.checkBounds", "false") - System.setProperty("io.netty.buffer.checkAccessible", "false") - - val settings = Settings() - val store = BenchmarkJasyncStore("postgresql") - val templateEngine = RockerAdapter() - val templateUrl = URL("classpath:fortunes.rocker.html") - val engine = NettyEpollServerAdapter(bossGroupThreads = 48) - - val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) - benchmark.server.start() -} diff --git a/frameworks/Kotlin/hexagon/store_jasync/build.gradle b/frameworks/Kotlin/hexagon/store_jasync/build.gradle deleted file mode 100644 index 5ead678dd16..00000000000 --- a/frameworks/Kotlin/hexagon/store_jasync/build.gradle +++ /dev/null @@ -1,5 +0,0 @@ - -dependencies { - api(project(":core_async")) - implementation("com.github.jasync-sql:jasync-postgresql:$jasyncVersion") -} diff --git a/frameworks/Kotlin/hexagon/store_jasync/src/main/kotlin/BenchmarkJasyncStore.kt b/frameworks/Kotlin/hexagon/store_jasync/src/main/kotlin/BenchmarkJasyncStore.kt deleted file mode 100644 index 0f5702c5e84..00000000000 --- a/frameworks/Kotlin/hexagon/store_jasync/src/main/kotlin/BenchmarkJasyncStore.kt +++ /dev/null @@ -1,106 +0,0 @@ -package com.hexagonkt.async.store - -import com.github.jasync.sql.db.ConnectionPoolConfigurationBuilder -import com.github.jasync.sql.db.pool.ConnectionPool -import com.github.jasync.sql.db.postgresql.PostgreSQLConnection -import com.github.jasync.sql.db.postgresql.PostgreSQLConnectionBuilder -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 org.cache2k.Cache -import java.util.concurrent.CompletableFuture -import java.util.concurrent.CompletableFuture.allOf - -class BenchmarkJasyncStore( - 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 dataSource: ConnectionPool by lazy { - ConnectionPoolConfigurationBuilder().let { - val environment = Jvm.systemSettingOrNull("BENCHMARK_ENV")?.lowercase() - val cpuCount = Jvm.cpuCount - - it.maxActiveConnections = 8 + if (environment == "citrine") cpuCount else cpuCount * 2 - it.host = Jvm.systemSettingOrNull("${engine.uppercase()}_DB_HOST") ?: "tfb-database" - it.database = settings.databaseName - it.username = settings.databaseUsername - it.password = settings.databasePassword - - PostgreSQLConnectionBuilder.createConnectionPool(it.build()) - } - } - - override fun findAllFortunes(): CompletableFuture> = - dataSource.sendPreparedStatement(SELECT_ALL_FORTUNES) - .thenApply { result -> - val rowSet = result.rows - rowSet.map { row -> - val id = row.getInt(0) ?: error("") - val message = row.getString(1) ?: error("") - Fortune(id, message) - } - } - - override fun findWorlds(ids: List): CompletableFuture> { - val futures = ids.map { findWorld(it, dataSource) }.toTypedArray() - return allOf(*futures).thenApply { futures.map { f -> f.get() ?: error("") } } - } - - override fun replaceWorlds(worlds: List): CompletableFuture<*> { - val futures = worlds.map { - val worldId = it.id - val newRandomNumber = it.randomNumber - dataSource - .sendPreparedStatement(SELECT_WORLD, listOf(worldId)) - .thenApply { rowSet -> - val row = rowSet.rows.iterator().next() - row.getInt(1) // Read 'randomNumber' to comply with Test type 5, point 6 - dataSource - .sendPreparedStatement(UPDATE_WORLD, listOf(newRandomNumber, worldId)) - } - }.toTypedArray() - - return allOf(*futures).thenApply { futures.map { f -> f.get() ?: error("") } } - } - - override fun initWorldsCache(cache: Cache) { - dataSource - .sendPreparedStatement("select * from world") - .thenApply { rowSet -> - rowSet.rows.map { row -> - val id = row.getInt(0) ?: error("") - val randomNumber = row.getInt(1) ?: error("") - cache.put(id, CachedWorld(id, randomNumber)) - } - } - .get() - } - - override fun loadCachedWorld(id: Int): CachedWorld = - findWorld(id, dataSource) - .thenApply { world -> CachedWorld(world.id, world.randomNumber) } - .get() - - override fun close() { - dataSource.disconnect().get() - } - - private fun findWorld(id: Int, client: ConnectionPool<*>): CompletableFuture = - client - .sendPreparedStatement(SELECT_WORLD, listOf(id)) - .thenApply { rowSet -> - val row = rowSet.rows.iterator().next() - val id1 = row.getInt(0) ?: error("") - val randomNumber = row.getInt(1) ?: error("") - World(id1, randomNumber) - } -} From da155321b774f18accc5d4880b830b9afb101fc0 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Mon, 10 Jul 2023 19:39:52 +0200 Subject: [PATCH 098/149] Update --- ...hexagon-nettyepoll-async-jasync.dockerfile | 23 ------------------- 1 file changed, 23 deletions(-) delete mode 100644 frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-jasync.dockerfile diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-jasync.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-jasync.dockerfile deleted file mode 100644 index aae9e180c7d..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-jasync.dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# -# BUILD -# -FROM docker.io/gradle:8.2-jdk17-alpine AS build -USER root -WORKDIR /hexagon - -ADD . . -RUN gradle --quiet classes -RUN gradle --quiet -x test installDist - -# -# RUNTIME -# -FROM docker.io/eclipse-temurin:17-jre-alpine -ARG PROJECT=hexagon_nettyepoll_async_pgclient - -ENV POSTGRESQL_DB_HOST tfb-database -ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA - -COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT - -ENTRYPOINT [ "/opt/hexagon_nettyepoll_async_pgclient/bin/hexagon_nettyepoll_async_pgclient" ] From 8bf5f23aa2bf2eff013b517166fe67bea9b99512 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Mon, 10 Jul 2023 19:53:05 +0200 Subject: [PATCH 099/149] Update --- .../Kotlin/hexagon/benchmark_config.json | 60 +++---------------- frameworks/Kotlin/hexagon/config.toml | 20 +------ .../hexagon/hexagon-jetty-native.dockerfile | 21 ------- .../hexagon-netty-async-pgclient.dockerfile | 23 ------- 4 files changed, 9 insertions(+), 115 deletions(-) delete mode 100644 frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile delete mode 100644 frameworks/Kotlin/hexagon/hexagon-netty-async-pgclient.dockerfile diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index a9e45ab3204..7319f7f601a 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -92,7 +92,7 @@ "notes": "http://hexagonkt.com", "versus": "netty" }, - "nettyepoll": { + "netty-native": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -111,53 +111,11 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Netty Epoll PostgreSQL", - "notes": "http://hexagonkt.com", - "versus": "netty" - }, - "nettyepoll-pgclient": { - "db_url": "/db", - "query_url": "/query?queries=", - "fortune_url": "/fortunes", - "update_url": "/update?queries=", - "cached_query_url": "/cached-queries?count=", - "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" - }, - "nettyepoll-async-pgclient": { - "db_url": "/db", - "query_url": "/query?queries=", - "fortune_url": "/fortunes", - "update_url": "/update?queries=", - "cached_query_url": "/cached-queries?count=", - "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 Async PgClient", + "display_name": "Hexagon Netty Native PostgreSQL", "notes": "http://hexagonkt.com", "versus": "netty" }, - "nettyepoll-async-jasync": { + "nettyepoll": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -176,11 +134,11 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Netty Epoll Async Jasync", + "display_name": "Hexagon Netty Epoll PostgreSQL", "notes": "http://hexagonkt.com", "versus": "netty" }, - "netty-native": { + "nettyepoll-async-pgclient": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -199,18 +157,16 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Netty Native PostgreSQL", + "display_name": "Hexagon Netty Epoll Async PgClient", "notes": "http://hexagonkt.com", "versus": "netty" }, - "nettyepoll-async-pgclient": { - "json_url": "/json", + "nettyepoll-pgclient": { "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", @@ -222,7 +178,7 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Netty Async PgClient", + "display_name": "Hexagon Netty Epoll PgClient", "notes": "http://hexagonkt.com", "versus": "netty" }, diff --git a/frameworks/Kotlin/hexagon/config.toml b/frameworks/Kotlin/hexagon/config.toml index a670485de47..edb6b6e4a5f 100644 --- a/frameworks/Kotlin/hexagon/config.toml +++ b/frameworks/Kotlin/hexagon/config.toml @@ -109,24 +109,6 @@ 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" - [nettyepoll-async-pgclient] urls.plaintext = "/plaintext" urls.json = "/json" @@ -145,7 +127,7 @@ platform = "Netty" webserver = "None" versus = "netty" -[nettyepoll-async-pgclient] +[nettyepoll-pgclient] urls.plaintext = "/plaintext" urls.json = "/json" urls.db = "/db" diff --git a/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile deleted file mode 100644 index 223aae81894..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -# -# BUILD -# -FROM ghcr.io/graalvm/native-image:ol9-java17-22.3.2 as build -USER root -WORKDIR /hexagon - -ADD . . -RUN microdnf -y install findutils -RUN ./gradlew --quiet classes -RUN ./gradlew --quiet -x test nativeCompile - -# -# RUNTIME -# -FROM scratch -ARG PROJECT=hexagon_jetty_postgresql - -COPY --from=build /hexagon/$PROJECT/build/native/nativeCompile/$PROJECT / - -ENTRYPOINT [ "/hexagon_jetty_postgresql" ] diff --git a/frameworks/Kotlin/hexagon/hexagon-netty-async-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-netty-async-pgclient.dockerfile deleted file mode 100644 index ddb35d90de8..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon-netty-async-pgclient.dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# -# BUILD -# -FROM docker.io/gradle:8.2-jdk17-alpine AS build -USER root -WORKDIR /hexagon - -ADD . . -RUN gradle --quiet classes -RUN gradle --quiet -x test installDist - -# -# RUNTIME -# -FROM docker.io/eclipse-temurin:17-jre-alpine -ARG PROJECT=hexagon_netty_async_pgclient - -ENV POSTGRESQL_DB_HOST tfb-database -ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA - -COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT - -ENTRYPOINT [ "/opt/hexagon_netty_async_pgclient/bin/hexagon_netty_async_pgclient" ] From c55d98afa600bf3c5ddc36f7cc674bb12d0888dd Mon Sep 17 00:00:00 2001 From: jaguililla Date: Mon, 10 Jul 2023 20:47:53 +0200 Subject: [PATCH 100/149] Update Gradle --- .../hexagon/gradle/wrapper/gradle-wrapper.jar | Bin 62076 -> 63375 bytes .../gradle/wrapper/gradle-wrapper.properties | 3 ++- frameworks/Kotlin/hexagon/gradlew | 5 ++++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar index c1962a79e29d3e0ab67b14947c167a862655af9b..033e24c4cdf41af1ab109bc7f253b2b887023340 100644 GIT binary patch delta 16170 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 delta 14892 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 diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties index ed4fda0fcea..ab1eb5eecd1 100644 --- a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties +++ b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https://services.gradle.org/distributions/gradle-8.2.1-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/frameworks/Kotlin/hexagon/gradlew b/frameworks/Kotlin/hexagon/gradlew index aeb74cbb43e..fcb6fca147c 100755 --- a/frameworks/Kotlin/hexagon/gradlew +++ b/frameworks/Kotlin/hexagon/gradlew @@ -130,10 +130,13 @@ 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. + if ! command -v java >/dev/null 2>&1 + then + 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 fi # Increase the maximum file descriptors if we can. From 5083e68d01c43e03cafcdbd524ffc3f81d25d5eb Mon Sep 17 00:00:00 2001 From: jaguililla Date: Mon, 10 Jul 2023 20:50:12 +0200 Subject: [PATCH 101/149] Benchmark Netty Epoll only --- .../hexagon_netty_async_pgclient/build.gradle | 7 ------ .../src/main/kotlin/Benchmark.kt | 25 ------------------- .../src/main/kotlin/Benchmark.kt | 24 ------------------ .../build.gradle | 1 + 4 files changed, 1 insertion(+), 56 deletions(-) delete mode 100644 frameworks/Kotlin/hexagon/hexagon_netty_async_pgclient/build.gradle delete mode 100644 frameworks/Kotlin/hexagon/hexagon_netty_async_pgclient/src/main/kotlin/Benchmark.kt delete mode 100644 frameworks/Kotlin/hexagon/hexagon_netty_postgresql/src/main/kotlin/Benchmark.kt diff --git a/frameworks/Kotlin/hexagon/hexagon_netty_async_pgclient/build.gradle b/frameworks/Kotlin/hexagon/hexagon_netty_async_pgclient/build.gradle deleted file mode 100644 index f29d1703b61..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon_netty_async_pgclient/build.gradle +++ /dev/null @@ -1,7 +0,0 @@ - -apply(from: "$gradleScripts/application.gradle") - -dependencies { - api(project(":store_pgclient_async")) - api("com.hexagonkt:http_server_netty_async:$hexagonVersion") -} diff --git a/frameworks/Kotlin/hexagon/hexagon_netty_async_pgclient/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_netty_async_pgclient/src/main/kotlin/Benchmark.kt deleted file mode 100644 index e5a9de4c597..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon_netty_async_pgclient/src/main/kotlin/Benchmark.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.hexagonkt - -import com.hexagonkt.async.Benchmark -import com.hexagonkt.async.store.BenchmarkPgClientStore -import com.hexagonkt.http.server.netty.async.NettyServerAdapter -import com.hexagonkt.templates.rocker.RockerAdapter -import io.netty.util.ResourceLeakDetector -import io.netty.util.ResourceLeakDetector.Level.DISABLED -import java.net.URL - -fun main() { - ResourceLeakDetector.setLevel(DISABLED) - - System.setProperty("io.netty.buffer.checkBounds", "false") - System.setProperty("io.netty.buffer.checkAccessible", "false") - - val settings = Settings() - val store = BenchmarkPgClientStore("postgresql") - val templateEngine = RockerAdapter() - val templateUrl = URL("classpath:fortunes.rocker.html") - val engine = NettyServerAdapter(bossGroupThreads = 48) - - val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) - benchmark.server.start() -} diff --git a/frameworks/Kotlin/hexagon/hexagon_netty_postgresql/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_netty_postgresql/src/main/kotlin/Benchmark.kt deleted file mode 100644 index 2a95e7385fc..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon_netty_postgresql/src/main/kotlin/Benchmark.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.hexagonkt - -import com.hexagonkt.http.server.netty.NettyServerAdapter -import com.hexagonkt.store.BenchmarkSqlStore -import com.hexagonkt.templates.rocker.RockerAdapter -import io.netty.util.ResourceLeakDetector -import io.netty.util.ResourceLeakDetector.Level.DISABLED -import java.net.URL - -fun main() { - ResourceLeakDetector.setLevel(DISABLED) - - System.setProperty("io.netty.buffer.checkBounds", "false") - System.setProperty("io.netty.buffer.checkAccessible", "false") - - val settings = Settings() - val store = BenchmarkSqlStore("postgresql") - val templateEngine = RockerAdapter() - val templateUrl = URL("classpath:fortunes.rocker.html") - val engine = NettyServerAdapter() - - val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) - benchmark.server.start() -} diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/build.gradle b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/build.gradle index 243fa57c121..d3ce42499e4 100644 --- a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/build.gradle +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/build.gradle @@ -1,4 +1,5 @@ +apply(from: "$gradleScripts/native.gradle") apply(from: "$gradleScripts/application.gradle") dependencies { From 927a7001a1bc4e2e3713a599c2cac733b1213cdb Mon Sep 17 00:00:00 2001 From: jaguililla Date: Mon, 10 Jul 2023 20:54:37 +0200 Subject: [PATCH 102/149] Add Nima adapter --- .../Kotlin/hexagon/benchmark_config.json | 55 +++++++++++++------ frameworks/Kotlin/hexagon/config.toml | 36 +++++++++--- .../hexagon_nima_pgclient/build.gradle | 7 +++ .../src/main/kotlin/Benchmark.kt | 17 ++++++ .../build.gradle | 2 +- .../src/main/kotlin/Benchmark.kt | 17 ++++++ frameworks/Kotlin/hexagon/settings.gradle | 4 +- 7 files changed, 110 insertions(+), 28 deletions(-) create mode 100644 frameworks/Kotlin/hexagon/hexagon_nima_pgclient/build.gradle create mode 100644 frameworks/Kotlin/hexagon/hexagon_nima_pgclient/src/main/kotlin/Benchmark.kt rename frameworks/Kotlin/hexagon/{hexagon_netty_postgresql => hexagon_nima_postgresql}/build.gradle (70%) create mode 100644 frameworks/Kotlin/hexagon/hexagon_nima_postgresql/src/main/kotlin/Benchmark.kt diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index 7319f7f601a..a03055d3a3d 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -69,7 +69,7 @@ "notes": "http://hexagonkt.com", "versus": "servlet" }, - "netty": { + "nettyepoll": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -88,11 +88,11 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Netty PostgreSQL", + "display_name": "Hexagon Netty Epoll PostgreSQL", "notes": "http://hexagonkt.com", "versus": "netty" }, - "netty-native": { + "nettyepoll-async-pgclient": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -111,18 +111,16 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Netty Native PostgreSQL", + "display_name": "Hexagon Netty Epoll Async PgClient", "notes": "http://hexagonkt.com", "versus": "netty" }, - "nettyepoll": { - "json_url": "/json", + "nettyepoll-pgclient": { "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", @@ -134,11 +132,11 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Netty Epoll PostgreSQL", + "display_name": "Hexagon Netty Epoll PgClient", "notes": "http://hexagonkt.com", "versus": "netty" }, - "nettyepoll-async-pgclient": { + "nima": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -153,20 +151,22 @@ "framework": "Hexagon", "language": "Kotlin", "orm": "Raw", - "platform": "Netty", + "platform": "Helidon", "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Netty Epoll Async PgClient", + "display_name": "Hexagon Nima PostgreSQL", "notes": "http://hexagonkt.com", - "versus": "netty" + "versus": "helidon-nima" }, - "nettyepoll-pgclient": { + "nima-native": { + "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", @@ -174,13 +174,36 @@ "framework": "Hexagon", "language": "Kotlin", "orm": "Raw", - "platform": "Netty", + "platform": "Helidon", "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Netty Epoll PgClient", + "display_name": "Hexagon Nima Native PostgreSQL", "notes": "http://hexagonkt.com", - "versus": "netty" + "versus": "helidon-nima" + }, + "nima-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": "Helidon", + "webserver": "None", + "os": "Linux", + "database_os": "Linux", + "display_name": "Hexagon Nima PgClient", + "notes": "http://hexagonkt.com", + "versus": "helidon-nima" }, "tomcat": { "json_url": "/json", diff --git a/frameworks/Kotlin/hexagon/config.toml b/frameworks/Kotlin/hexagon/config.toml index edb6b6e4a5f..10a0418dbe4 100644 --- a/frameworks/Kotlin/hexagon/config.toml +++ b/frameworks/Kotlin/hexagon/config.toml @@ -55,7 +55,7 @@ platform = "Servlet" webserver = "None" versus = "servlet" -[netty] +[nettyepoll] urls.plaintext = "/plaintext" urls.json = "/json" urls.db = "/db" @@ -73,7 +73,7 @@ platform = "Netty" webserver = "None" versus = "netty" -[netty-native] +[nettyepoll-async-pgclient] urls.plaintext = "/plaintext" urls.json = "/json" urls.db = "/db" @@ -91,7 +91,7 @@ platform = "Netty" webserver = "None" versus = "netty" -[nettyepoll] +[nettyepoll-pgclient] urls.plaintext = "/plaintext" urls.json = "/json" urls.db = "/db" @@ -109,7 +109,7 @@ platform = "Netty" webserver = "None" versus = "netty" -[nettyepoll-async-pgclient] +[nima] urls.plaintext = "/plaintext" urls.json = "/json" urls.db = "/db" @@ -123,11 +123,11 @@ database = "postgres" database_os = "Linux" os = "Linux" orm = "Raw" -platform = "Netty" +platform = "Helidon" webserver = "None" -versus = "netty" +versus = "helidon-nima" -[nettyepoll-pgclient] +[nima-native] urls.plaintext = "/plaintext" urls.json = "/json" urls.db = "/db" @@ -141,9 +141,27 @@ database = "postgres" database_os = "Linux" os = "Linux" orm = "Raw" -platform = "Netty" +platform = "Helidon" webserver = "None" -versus = "netty" +versus = "helidon-nima" + +[nima-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 = "Helidon" +webserver = "None" +versus = "helidon-nima" [tomcat] urls.plaintext = "/plaintext" diff --git a/frameworks/Kotlin/hexagon/hexagon_nima_pgclient/build.gradle b/frameworks/Kotlin/hexagon/hexagon_nima_pgclient/build.gradle new file mode 100644 index 00000000000..86d2692a326 --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_nima_pgclient/build.gradle @@ -0,0 +1,7 @@ + +apply(from: "$gradleScripts/application.gradle") + +dependencies { + api(project(":store_pgclient")) + api("com.hexagonkt:http_server_nima:$hexagonVersion") +} diff --git a/frameworks/Kotlin/hexagon/hexagon_nima_pgclient/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_nima_pgclient/src/main/kotlin/Benchmark.kt new file mode 100644 index 00000000000..9df2914829b --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_nima_pgclient/src/main/kotlin/Benchmark.kt @@ -0,0 +1,17 @@ +package com.hexagonkt + +import com.hexagonkt.core.urlOf +import com.hexagonkt.http.server.nima.NimaServerAdapter +import com.hexagonkt.store.BenchmarkPgClientStore +import com.hexagonkt.templates.rocker.RockerAdapter + +fun main() { + val settings = Settings() + val store = BenchmarkPgClientStore("postgresql") + val templateEngine = RockerAdapter() + val templateUrl = urlOf("classpath:fortunes.rocker.html") + val engine = NimaServerAdapter() + + val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) + benchmark.server.start() +} diff --git a/frameworks/Kotlin/hexagon/hexagon_netty_postgresql/build.gradle b/frameworks/Kotlin/hexagon/hexagon_nima_postgresql/build.gradle similarity index 70% rename from frameworks/Kotlin/hexagon/hexagon_netty_postgresql/build.gradle rename to frameworks/Kotlin/hexagon/hexagon_nima_postgresql/build.gradle index 01884cb3583..2957919e905 100644 --- a/frameworks/Kotlin/hexagon/hexagon_netty_postgresql/build.gradle +++ b/frameworks/Kotlin/hexagon/hexagon_nima_postgresql/build.gradle @@ -4,5 +4,5 @@ apply(from: "$gradleScripts/native.gradle") dependencies { api(project(":store_sql")) - api("com.hexagonkt:http_server_netty:$hexagonVersion") + api("com.hexagonkt:http_server_nima:$hexagonVersion") } diff --git a/frameworks/Kotlin/hexagon/hexagon_nima_postgresql/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_nima_postgresql/src/main/kotlin/Benchmark.kt new file mode 100644 index 00000000000..16e4797e37a --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_nima_postgresql/src/main/kotlin/Benchmark.kt @@ -0,0 +1,17 @@ +package com.hexagonkt + +import com.hexagonkt.core.urlOf +import com.hexagonkt.http.server.nima.NimaServerAdapter +import com.hexagonkt.store.BenchmarkSqlStore +import com.hexagonkt.templates.rocker.RockerAdapter + +fun main() { + val settings = Settings() + val store = BenchmarkSqlStore("postgresql") + val templateEngine = RockerAdapter() + val templateUrl = urlOf("classpath:fortunes.rocker.html") + val engine = NimaServerAdapter() + + val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) + benchmark.server.start() +} diff --git a/frameworks/Kotlin/hexagon/settings.gradle b/frameworks/Kotlin/hexagon/settings.gradle index cf4ad98fdac..2b234d2bbc6 100644 --- a/frameworks/Kotlin/hexagon/settings.gradle +++ b/frameworks/Kotlin/hexagon/settings.gradle @@ -9,8 +9,8 @@ include( "hexagon_jetty_pgclient", "hexagon_jetty_postgresql", - "hexagon_netty_postgresql", - "hexagon_netty_async_pgclient", + "hexagon_nima_pgclient", + "hexagon_nima_postgresql", "hexagon_nettyepoll_pgclient", "hexagon_nettyepoll_async_pgclient", "hexagon_nettyepoll_postgresql", From 494167f5a5d87ff72fed01753af6b56f87aa3d07 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Mon, 10 Jul 2023 20:58:12 +0200 Subject: [PATCH 103/149] Update container builds --- ...xagon-nettyepoll-async-pgclient.dockerfile | 2 +- .../hexagon-nettyepoll-pgclient.dockerfile | 2 +- ...kerfile => hexagon-nima-native.dockerfile} | 6 ++--- ...rfile => hexagon-nima-pgclient.dockerfile} | 4 ++-- .../Kotlin/hexagon/hexagon-nima.dockerfile | 23 +++++++++++++++++++ .../Kotlin/hexagon/hexagon-tomcat.dockerfile | 2 +- 6 files changed, 31 insertions(+), 8 deletions(-) rename frameworks/Kotlin/hexagon/{hexagon-netty-native.dockerfile => hexagon-nima-native.dockerfile} (64%) rename frameworks/Kotlin/hexagon/{hexagon-netty.dockerfile => hexagon-nima-pgclient.dockerfile} (78%) create mode 100644 frameworks/Kotlin/hexagon/hexagon-nima.dockerfile diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile index 7e4c80d6cd4..aae9e180c7d 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.1.1-jdk17-alpine AS build +FROM docker.io/gradle:8.2-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile index afe2e155ccc..e753730c6e4 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.1.1-jdk17-alpine AS build +FROM docker.io/gradle:8.2-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-netty-native.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile similarity index 64% rename from frameworks/Kotlin/hexagon/hexagon-netty-native.dockerfile rename to frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile index 5443b48eb8f..004b0dba351 100644 --- a/frameworks/Kotlin/hexagon/hexagon-netty-native.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM ghcr.io/graalvm/native-image:ol9-java17-22.3.2 as build +FROM ghcr.io/graalvm/native-image-community:17-ol9 as build USER root WORKDIR /hexagon @@ -14,8 +14,8 @@ RUN ./gradlew --quiet -x test nativeCompile # RUNTIME # FROM scratch -ARG PROJECT=hexagon_netty_postgresql +ARG PROJECT=hexagon_nima_postgresql COPY --from=build /hexagon/$PROJECT/build/native/nativeCompile/$PROJECT / -ENTRYPOINT [ "/hexagon_netty_postgresql" ] +ENTRYPOINT [ "/hexagon_nima_postgresql" ] diff --git a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile similarity index 78% rename from frameworks/Kotlin/hexagon/hexagon-netty.dockerfile rename to frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile index 16b71649263..88861993f80 100644 --- a/frameworks/Kotlin/hexagon/hexagon-netty.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile @@ -13,11 +13,11 @@ RUN gradle --quiet -x test installDist # RUNTIME # FROM docker.io/eclipse-temurin:17-jre-alpine -ARG PROJECT=hexagon_netty_postgresql +ARG PROJECT=hexagon_nima_pgclient ENV POSTGRESQL_DB_HOST tfb-database ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT -ENTRYPOINT [ "/opt/hexagon_netty_postgresql/bin/hexagon_netty_postgresql" ] +ENTRYPOINT [ "/opt/hexagon_nima_pgclient/bin/hexagon_nima_pgclient" ] diff --git a/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile new file mode 100644 index 00000000000..64e403b8eed --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile @@ -0,0 +1,23 @@ +# +# BUILD +# +FROM docker.io/gradle:8.2-jdk17-alpine AS build +USER root +WORKDIR /hexagon + +ADD . . +RUN gradle --quiet classes +RUN gradle --quiet -x test installDist + +# +# RUNTIME +# +FROM docker.io/eclipse-temurin:17-jre-alpine +ARG PROJECT=hexagon_nima_postgresql + +ENV POSTGRESQL_DB_HOST tfb-database +ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA + +COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT + +ENTRYPOINT [ "/opt/hexagon_nima_postgresql/bin/hexagon_nima_postgresql" ] diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index e35db7b9f68..7fd1f9ca4e4 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.1.1-jdk17-alpine AS build +FROM docker.io/gradle:8.2-jdk17-alpine AS build USER root WORKDIR /hexagon From 8c6ae8e8a7830e529eb288076bbf45c2576b54ea Mon Sep 17 00:00:00 2001 From: jaguililla Date: Mon, 10 Jul 2023 21:05:04 +0200 Subject: [PATCH 104/149] Fix missing endpoints --- frameworks/Kotlin/hexagon/benchmark_config.json | 4 ++++ frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index a03055d3a3d..f88f6dcd6da 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -49,11 +49,13 @@ "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", @@ -116,11 +118,13 @@ "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", diff --git a/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile index 004b0dba351..2f43ec310d0 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM ghcr.io/graalvm/native-image-community:17-ol9 as build +FROM ghcr.io/graalvm/native-image-community:20-ol9 as build USER root WORKDIR /hexagon From 8917827356bcb7368fbd3833336ef1eca363a35f Mon Sep 17 00:00:00 2001 From: jaguililla Date: Mon, 10 Jul 2023 21:45:56 +0200 Subject: [PATCH 105/149] Fix Nima benchmarks --- .../Kotlin/hexagon/benchmark_config.json | 23 ------------------- frameworks/Kotlin/hexagon/config.toml | 18 --------------- .../hexagon/hexagon-nima-native.dockerfile | 21 ----------------- .../hexagon/hexagon-nima-pgclient.dockerfile | 4 ++-- .../Kotlin/hexagon/hexagon-nima.dockerfile | 4 ++-- 5 files changed, 4 insertions(+), 66 deletions(-) delete mode 100644 frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index f88f6dcd6da..c98335451d2 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -163,29 +163,6 @@ "notes": "http://hexagonkt.com", "versus": "helidon-nima" }, - "nima-native": { - "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": "Helidon", - "webserver": "None", - "os": "Linux", - "database_os": "Linux", - "display_name": "Hexagon Nima Native PostgreSQL", - "notes": "http://hexagonkt.com", - "versus": "helidon-nima" - }, "nima-pgclient": { "json_url": "/json", "db_url": "/db", diff --git a/frameworks/Kotlin/hexagon/config.toml b/frameworks/Kotlin/hexagon/config.toml index 10a0418dbe4..5629b5a7d8d 100644 --- a/frameworks/Kotlin/hexagon/config.toml +++ b/frameworks/Kotlin/hexagon/config.toml @@ -127,24 +127,6 @@ platform = "Helidon" webserver = "None" versus = "helidon-nima" -[nima-native] -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 = "Helidon" -webserver = "None" -versus = "helidon-nima" - [nima-pgclient] urls.plaintext = "/plaintext" urls.json = "/json" diff --git a/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile deleted file mode 100644 index 2f43ec310d0..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -# -# BUILD -# -FROM ghcr.io/graalvm/native-image-community:20-ol9 as build -USER root -WORKDIR /hexagon - -ADD . . -RUN microdnf -y install findutils -RUN ./gradlew --quiet classes -RUN ./gradlew --quiet -x test nativeCompile - -# -# RUNTIME -# -FROM scratch -ARG PROJECT=hexagon_nima_postgresql - -COPY --from=build /hexagon/$PROJECT/build/native/nativeCompile/$PROJECT / - -ENTRYPOINT [ "/hexagon_nima_postgresql" ] diff --git a/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile index 88861993f80..f99ae730145 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile @@ -12,11 +12,11 @@ RUN gradle --quiet -x test installDist # # RUNTIME # -FROM docker.io/eclipse-temurin:17-jre-alpine +FROM docker.io/eclipse-temurin:20-jre-alpine ARG PROJECT=hexagon_nima_pgclient ENV POSTGRESQL_DB_HOST tfb-database -ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA +ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT diff --git a/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile index 64e403b8eed..cfb1f55454d 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile @@ -12,11 +12,11 @@ RUN gradle --quiet -x test installDist # # RUNTIME # -FROM docker.io/eclipse-temurin:17-jre-alpine +FROM docker.io/eclipse-temurin:20-jre-alpine ARG PROJECT=hexagon_nima_postgresql ENV POSTGRESQL_DB_HOST tfb-database -ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA +ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT From c1e45d26d78dcc2b774fe8e2debc0ed818816109 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 3 Aug 2023 09:11:03 +0200 Subject: [PATCH 106/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index fecbf1174e6..c8031c34b7e 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -9,9 +9,9 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.0.0-B8" + hexagonVersion = "3.0.0-B9" jettyVersion = "11.0.15" - nettyVersion = "4.1.94.Final" + nettyVersion = "4.1.96.Final" hikariVersion = "5.0.1" postgresqlVersion = "42.6.0" From 58635b12866ca95c5566086dabc18717c7db54bb Mon Sep 17 00:00:00 2001 From: jaguililla Date: Tue, 15 Aug 2023 19:53:44 +0200 Subject: [PATCH 107/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 6 +- .../Kotlin/hexagon/core_async/build.gradle | 32 ----- .../core_async/src/main/kotlin/Benchmark.kt | 28 ---- .../core_async/src/main/kotlin/Controller.kt | 133 ------------------ .../src/main/kotlin/store/BenchmarkStore.kt | 34 ----- .../core/native-image.properties | 7 - .../core/reflect-config.json | 23 --- .../src/main/resources/fortunes.rocker.html | 24 ---- .../hexagon-jettyloom-pgclient.dockerfile | 2 +- .../hexagon/hexagon-jettyloom.dockerfile | 2 +- ...xagon-nettyepoll-async-pgclient.dockerfile | 23 --- .../hexagon-nettyepoll-pgclient.dockerfile | 2 +- .../hexagon/hexagon-nettyepoll.dockerfile | 2 +- .../hexagon/hexagon-nima-native.dockerfile | 21 +++ .../hexagon/hexagon-nima-pgclient.dockerfile | 2 +- .../Kotlin/hexagon/hexagon-nima.dockerfile | 2 +- .../Kotlin/hexagon/hexagon-tomcat.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon.dockerfile | 2 +- .../build.gradle | 8 -- .../src/main/kotlin/Benchmark.kt | 33 ----- frameworks/Kotlin/hexagon/settings.gradle | 4 +- .../hexagon/store_pgclient_async/build.gradle | 6 - .../src/main/kotlin/BenchmarkPgClientStore.kt | 114 --------------- 23 files changed, 33 insertions(+), 479 deletions(-) delete mode 100644 frameworks/Kotlin/hexagon/core_async/build.gradle delete mode 100644 frameworks/Kotlin/hexagon/core_async/src/main/kotlin/Benchmark.kt delete mode 100644 frameworks/Kotlin/hexagon/core_async/src/main/kotlin/Controller.kt delete mode 100644 frameworks/Kotlin/hexagon/core_async/src/main/kotlin/store/BenchmarkStore.kt delete mode 100644 frameworks/Kotlin/hexagon/core_async/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties delete mode 100644 frameworks/Kotlin/hexagon/core_async/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/reflect-config.json delete mode 100644 frameworks/Kotlin/hexagon/core_async/src/main/resources/fortunes.rocker.html delete mode 100644 frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile create mode 100644 frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile delete mode 100644 frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/build.gradle delete mode 100644 frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/src/main/kotlin/Benchmark.kt delete mode 100644 frameworks/Kotlin/hexagon/store_pgclient_async/build.gradle delete mode 100644 frameworks/Kotlin/hexagon/store_pgclient_async/src/main/kotlin/BenchmarkPgClientStore.kt diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index c8031c34b7e..669495460e6 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,7 +1,7 @@ plugins { id "org.jetbrains.kotlin.jvm" version "1.9.0" apply false - id "org.graalvm.buildtools.native" version "0.9.23" apply false + id "org.graalvm.buildtools.native" version "0.9.24" apply false } version = "1.0.0" @@ -9,8 +9,8 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.0.0-B9" - jettyVersion = "11.0.15" + hexagonVersion = "3.0.0" + jettyVersion = "12.0.0" nettyVersion = "4.1.96.Final" hikariVersion = "5.0.1" diff --git a/frameworks/Kotlin/hexagon/core_async/build.gradle b/frameworks/Kotlin/hexagon/core_async/build.gradle deleted file mode 100644 index 0a33387738e..00000000000 --- a/frameworks/Kotlin/hexagon/core_async/build.gradle +++ /dev/null @@ -1,32 +0,0 @@ - -plugins { - id("nu.studer.rocker") version("3.0.4") -} - -dependencies { - api(project(":model")) - api("com.hexagonkt:http_server_async:$hexagonVersion") - api("com.hexagonkt:templates_rocker:$hexagonVersion") - api("com.hexagonkt:logging_slf4j_jul:$hexagonVersion") - api("com.hexagonkt:serialization_jackson_json:$hexagonVersion") - api("org.cache2k:cache2k-core:$cache2kVersion") -} - -tasks.register("minimizeTemplate") { - doLast { - File template = file("$buildDir/resources/main/fortunes.rocker.html") - List lines = template.readLines().collect { it.trim() } - template.write(lines.join("")) - } -} - -jar.dependsOn("minimizeTemplate") - -rocker { - configurations { - create("main") { - templateDir.set(file("src/main/resources")) - optimize.set(true) - } - } -} diff --git a/frameworks/Kotlin/hexagon/core_async/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/core_async/src/main/kotlin/Benchmark.kt deleted file mode 100644 index 2bda28da73e..00000000000 --- a/frameworks/Kotlin/hexagon/core_async/src/main/kotlin/Benchmark.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.hexagonkt.async - -import com.hexagonkt.Settings -import com.hexagonkt.http.server.async.HttpServer -import com.hexagonkt.http.server.async.HttpServerPort -import com.hexagonkt.http.server.async.HttpServerSettings -import com.hexagonkt.async.store.BenchmarkStore -import com.hexagonkt.templates.TemplatePort -import java.net.InetAddress -import java.net.URL - -class Benchmark( - private val engine: HttpServerPort, - private val store: BenchmarkStore, - private val template: TemplatePort, - private val templateUrl: URL, - private val settings: Settings = Settings(), -) { - val server: HttpServer by lazy { - val controller = Controller(settings, store, template, templateUrl) - val serverSettings = HttpServerSettings( - bindAddress = InetAddress.getByName(settings.bindAddress), - bindPort = settings.bindPort, - ) - - HttpServer(engine, controller.path, serverSettings) - } -} diff --git a/frameworks/Kotlin/hexagon/core_async/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/core_async/src/main/kotlin/Controller.kt deleted file mode 100644 index 683d39f4ffa..00000000000 --- a/frameworks/Kotlin/hexagon/core_async/src/main/kotlin/Controller.kt +++ /dev/null @@ -1,133 +0,0 @@ -package com.hexagonkt.async - -import com.hexagonkt.Settings -import com.hexagonkt.core.fieldsMapOf -import com.hexagonkt.core.media.APPLICATION_JSON -import com.hexagonkt.core.media.TEXT_HTML -import com.hexagonkt.core.media.TEXT_PLAIN -import com.hexagonkt.handlers.async.done -import com.hexagonkt.http.model.ContentType -import com.hexagonkt.http.model.Header -import com.hexagonkt.http.model.Headers -import com.hexagonkt.http.server.async.callbacks.DateCallback -import com.hexagonkt.http.handlers.async.HttpContext -import com.hexagonkt.http.handlers.async.PathHandler -import com.hexagonkt.http.handlers.async.path -import com.hexagonkt.model.* -import com.hexagonkt.serialization.jackson.json.Json -import com.hexagonkt.serialization.serialize -import com.hexagonkt.async.store.BenchmarkStore -import com.hexagonkt.templates.TemplatePort -import java.net.URL -import java.util.concurrent.CompletableFuture -import java.util.concurrent.ThreadLocalRandom -import kotlin.text.Charsets.UTF_8 - -class Controller( - settings: Settings, - store: BenchmarkStore, - templateEngine: TemplatePort, - templateUrl: URL, -) { - private val queriesParam: String = settings.queriesParam - private val cachedQueriesParam: String = settings.cachedQueriesParam - private val worldRows: Int = settings.worldRows - private val textMessage: String = settings.textMessage - - private val plain: ContentType = ContentType(TEXT_PLAIN) - private val json: ContentType = ContentType(APPLICATION_JSON) - private val html: ContentType = ContentType(TEXT_HTML, charset = UTF_8) - - private val headers = Headers(Header("server", "Hexagon")) - - val path: PathHandler by lazy { - path { - on("*") { send(headers = headers).done() } - on("*", DateCallback()) - - get("/plaintext") { ok(textMessage, contentType = plain).done() } - get("/json") { ok(Message(textMessage).toJson(), contentType = json).done() } - get("/fortunes") { listFortunes(store, templateUrl, templateEngine) } - get("/db") { dbQuery(store) } - get("/query") { getWorlds(store) } - get("/cached-queries") { getCachedWorlds(store) } - get("/update") { updateWorlds(store) } - } - } - - private fun Message.toJson(): String = - toMap().serialize(Json.raw) - - private fun HttpContext.listFortunes( - store: BenchmarkStore, templateUrl: URL, templateAdapter: TemplatePort - ): CompletableFuture = - store - .findAllFortunes() - .thenApply { it + Fortune(0, "Additional fortune added at request time.") } - .thenApply { fortunes -> fortunes.sortedBy { it.message } } - .thenApply { sortedFortunes -> mapOf("fortunes" to sortedFortunes) } - .thenApply { context -> templateAdapter.render(templateUrl, context) } - .thenApply { body -> ok(body, contentType = html) } - - private fun HttpContext.dbQuery(store: BenchmarkStore): CompletableFuture { - val ids = listOf(randomWorld()) - return store.findWorlds(ids) - .thenApply { worlds -> worlds.first().toMap()} - .thenApply { world -> sendJson(world) } - } - - private fun HttpContext.getWorlds(store: BenchmarkStore): CompletableFuture { - val worldsCount = getWorldsCount(queriesParam) - val ids = (1..worldsCount).map { randomWorld() } - return store.findWorlds(ids) - .thenApply { worlds -> worlds.map { it.toMap() } } - .thenApply { worlds -> sendJson(worlds) } - } - - private fun HttpContext.getCachedWorlds(store: BenchmarkStore): CompletableFuture { - val worldsCount = getWorldsCount(cachedQueriesParam) - val ids = (1..worldsCount).map { randomWorld() } - val worlds = store.findCachedWorlds(ids).map { it.toMap() } - - return sendJson(worlds).done() - } - - private fun HttpContext.updateWorlds(store: BenchmarkStore): CompletableFuture { - val worldsCount = getWorldsCount(queriesParam) - val worlds = (1..worldsCount).map { World(randomWorld(), randomWorld()) } - - return store.replaceWorlds(worlds) - .thenApply { sendJson(worlds.map { it.toMap() }) } - } - - private fun HttpContext.sendJson(body: Any): HttpContext = - ok(body.serialize(Json.raw), contentType = json) - - private fun HttpContext.getWorldsCount(parameter: String): Int = - request.queryParameters[parameter]?.string()?.toIntOrNull().let { - when { - it == null -> 1 - it < 1 -> 1 - it > 500 -> 500 - else -> it - } - } - - private fun randomWorld(): Int = - ThreadLocalRandom.current().nextInt(worldRows) + 1 - - private fun Message.toMap(): Map = - fieldsMapOf(Message::message to message) - - private fun World.toMap(): Map = - fieldsMapOf( - World::id to id, - World::randomNumber to randomNumber, - ) - - private fun CachedWorld.toMap(): Map = - fieldsMapOf( - CachedWorld::id to id, - CachedWorld::randomNumber to randomNumber, - ) -} diff --git a/frameworks/Kotlin/hexagon/core_async/src/main/kotlin/store/BenchmarkStore.kt b/frameworks/Kotlin/hexagon/core_async/src/main/kotlin/store/BenchmarkStore.kt deleted file mode 100644 index 13f5aae7108..00000000000 --- a/frameworks/Kotlin/hexagon/core_async/src/main/kotlin/store/BenchmarkStore.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.hexagonkt.async.store - -import com.hexagonkt.model.CachedWorld -import com.hexagonkt.model.Fortune -import com.hexagonkt.Settings -import com.hexagonkt.model.World -import org.cache2k.Cache -import org.cache2k.Cache2kBuilder -import java.util.concurrent.CompletableFuture - -abstract class BenchmarkStore(settings: Settings) { - - abstract fun findAllFortunes(): CompletableFuture> - abstract fun findWorlds(ids: List): CompletableFuture> - abstract fun replaceWorlds(worlds: List): CompletableFuture<*> - abstract fun initWorldsCache(cache: Cache) - abstract fun loadCachedWorld(id: Int): CachedWorld - abstract fun close() - - private val worldsCache: Cache by lazy { - object : Cache2kBuilder() {} - .eternal(true) - .disableMonitoring(true) - .disableStatistics(true) - .entryCapacity(settings.worldRows.toLong()) - .loader { id -> loadCachedWorld(id) } - .build() - .apply { initWorldsCache(this) } - } - - fun findCachedWorlds(ids: List): List { - return ids.mapNotNull { worldsCache.get(it) } - } -} diff --git a/frameworks/Kotlin/hexagon/core_async/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties b/frameworks/Kotlin/hexagon/core_async/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties deleted file mode 100644 index ee1c0199d95..00000000000 --- a/frameworks/Kotlin/hexagon/core_async/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties +++ /dev/null @@ -1,7 +0,0 @@ -Args= \ - -H:IncludeResources=.*\\.(html|class) \ - --enable-preview \ - --static \ - --initialize-at-build-time=org.slf4j.jul.JDK14LoggerAdapter \ - --initialize-at-build-time=org.slf4j.jul.JDK14LoggerAdapter$1 \ - --initialize-at-build-time=org.slf4j.LoggerFactory diff --git a/frameworks/Kotlin/hexagon/core_async/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/reflect-config.json b/frameworks/Kotlin/hexagon/core_async/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/reflect-config.json deleted file mode 100644 index 11815306be2..00000000000 --- a/frameworks/Kotlin/hexagon/core_async/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/reflect-config.json +++ /dev/null @@ -1,23 +0,0 @@ -[ - { - "name": "fortunes", - "allPublicMethods": true, - "allDeclaredFields": true, - "allDeclaredMethods": true, - "allDeclaredConstructors": true - }, - { - "name": "fortunes$Template", - "allPublicMethods": true, - "allDeclaredFields": true, - "allDeclaredMethods": true, - "allDeclaredConstructors": true - }, - { - "name": "fortunes$PlainText", - "allPublicMethods": true, - "allDeclaredFields": true, - "allDeclaredMethods": true, - "allDeclaredConstructors": true - } -] diff --git a/frameworks/Kotlin/hexagon/core_async/src/main/resources/fortunes.rocker.html b/frameworks/Kotlin/hexagon/core_async/src/main/resources/fortunes.rocker.html deleted file mode 100644 index c9a9d4037e5..00000000000 --- a/frameworks/Kotlin/hexagon/core_async/src/main/resources/fortunes.rocker.html +++ /dev/null @@ -1,24 +0,0 @@ -@import java.util.* -@import com.hexagonkt.model.Fortune -@args(Map context) - - - - - Fortunes - - - - - - - - @for ((fortune) : (Collection)context.get("fortunes")) { - - - - - } -
idmessage
@fortune.getId()@fortune.getMessage()
- - diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile index 390ce706bc6..ce47e8fcb97 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.2-jdk17-alpine AS build +FROM docker.io/gradle:8.2.1-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile index 97809e8cc05..464506eb198 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.2-jdk17-alpine AS build +FROM docker.io/gradle:8.2.1-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile deleted file mode 100644 index aae9e180c7d..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-async-pgclient.dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# -# BUILD -# -FROM docker.io/gradle:8.2-jdk17-alpine AS build -USER root -WORKDIR /hexagon - -ADD . . -RUN gradle --quiet classes -RUN gradle --quiet -x test installDist - -# -# RUNTIME -# -FROM docker.io/eclipse-temurin:17-jre-alpine -ARG PROJECT=hexagon_nettyepoll_async_pgclient - -ENV POSTGRESQL_DB_HOST tfb-database -ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA - -COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT - -ENTRYPOINT [ "/opt/hexagon_nettyepoll_async_pgclient/bin/hexagon_nettyepoll_async_pgclient" ] diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile index e753730c6e4..3ec94a9929d 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.2-jdk17-alpine AS build +FROM docker.io/gradle:8.2.1-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile index 9b083b9683d..1b3c56e1823 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.2-jdk17-alpine AS build +FROM docker.io/gradle:8.2.1-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile new file mode 100644 index 00000000000..004b0dba351 --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile @@ -0,0 +1,21 @@ +# +# BUILD +# +FROM ghcr.io/graalvm/native-image-community:17-ol9 as build +USER root +WORKDIR /hexagon + +ADD . . +RUN microdnf -y install findutils +RUN ./gradlew --quiet classes +RUN ./gradlew --quiet -x test nativeCompile + +# +# RUNTIME +# +FROM scratch +ARG PROJECT=hexagon_nima_postgresql + +COPY --from=build /hexagon/$PROJECT/build/native/nativeCompile/$PROJECT / + +ENTRYPOINT [ "/hexagon_nima_postgresql" ] diff --git a/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile index f99ae730145..d0db94e2eb3 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.2-jdk17-alpine AS build +FROM docker.io/gradle:8.2.1-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile index cfb1f55454d..18600a7beaf 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.2-jdk17-alpine AS build +FROM docker.io/gradle:8.2.1-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index 7fd1f9ca4e4..17c6f46db85 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.2-jdk17-alpine AS build +FROM docker.io/gradle:8.2.1-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index 2cf68db7f9f..bac92f13a42 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.2-jdk17-alpine AS build +FROM docker.io/gradle:8.2.1-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/build.gradle b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/build.gradle deleted file mode 100644 index 148de98b406..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/build.gradle +++ /dev/null @@ -1,8 +0,0 @@ - -apply(from: "$gradleScripts/application.gradle") - -dependencies { - api(project(":store_pgclient_async")) - api("com.hexagonkt:http_server_netty_epoll_async:$hexagonVersion") - api("io.netty:netty-transport-native-epoll:$nettyVersion:linux-x86_64") -} diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/src/main/kotlin/Benchmark.kt deleted file mode 100644 index 1e40fa3ffaf..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_async_pgclient/src/main/kotlin/Benchmark.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.hexagonkt - -import com.hexagonkt.async.Benchmark -import com.hexagonkt.async.store.BenchmarkPgClientStore -import com.hexagonkt.http.server.netty.epoll.async.NettyEpollServerAdapter -import com.hexagonkt.templates.rocker.RockerAdapter -import io.netty.util.ResourceLeakDetector -import io.netty.util.ResourceLeakDetector.Level.DISABLED -import java.net.URL - -fun main() { - ResourceLeakDetector.setLevel(DISABLED) - - System.setProperty("vertx.disableMetrics", "true") - System.setProperty("vertx.disableH2c", "true") - System.setProperty("vertx.disableWebsockets", "true") - System.setProperty("vertx.flashPolicyHandler", "false") - System.setProperty("vertx.threadChecks", "false") - System.setProperty("vertx.disableContextTimings", "true") - System.setProperty("vertx.disableTCCL", "true") - System.setProperty("vertx.disableHttpHeadersValidation", "true") - System.setProperty("io.netty.buffer.checkBounds", "false") - System.setProperty("io.netty.buffer.checkAccessible", "false") - - val settings = Settings() - val store = BenchmarkPgClientStore("postgresql") - val templateEngine = RockerAdapter() - val templateUrl = URL("classpath:fortunes.rocker.html") - val engine = NettyEpollServerAdapter(bossGroupThreads = 48) - - val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) - benchmark.server.start() -} diff --git a/frameworks/Kotlin/hexagon/settings.gradle b/frameworks/Kotlin/hexagon/settings.gradle index 2b234d2bbc6..a82f139234f 100644 --- a/frameworks/Kotlin/hexagon/settings.gradle +++ b/frameworks/Kotlin/hexagon/settings.gradle @@ -2,17 +2,15 @@ include( "model", "core", - "core_async", "store_pgclient", - "store_pgclient_async", "store_sql", + "test", "hexagon_jetty_pgclient", "hexagon_jetty_postgresql", "hexagon_nima_pgclient", "hexagon_nima_postgresql", "hexagon_nettyepoll_pgclient", - "hexagon_nettyepoll_async_pgclient", "hexagon_nettyepoll_postgresql", "hexagon_tomcat_postgresql", ) diff --git a/frameworks/Kotlin/hexagon/store_pgclient_async/build.gradle b/frameworks/Kotlin/hexagon/store_pgclient_async/build.gradle deleted file mode 100644 index 65d4ca18f97..00000000000 --- a/frameworks/Kotlin/hexagon/store_pgclient_async/build.gradle +++ /dev/null @@ -1,6 +0,0 @@ - -dependencies { - api(project(":core_async")) - implementation("io.vertx:vertx-pg-client:$vertxVersion") - implementation("com.ongres.scram:client:2.1") -} diff --git a/frameworks/Kotlin/hexagon/store_pgclient_async/src/main/kotlin/BenchmarkPgClientStore.kt b/frameworks/Kotlin/hexagon/store_pgclient_async/src/main/kotlin/BenchmarkPgClientStore.kt deleted file mode 100644 index 8266b3120e4..00000000000 --- a/frameworks/Kotlin/hexagon/store_pgclient_async/src/main/kotlin/BenchmarkPgClientStore.kt +++ /dev/null @@ -1,114 +0,0 @@ -package com.hexagonkt.async.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.CompositeFuture.all -import io.vertx.core.Future -import io.vertx.core.Vertx.vertx -import io.vertx.pgclient.PgConnectOptions -import io.vertx.pgclient.PgPool -import io.vertx.sqlclient.* -import org.cache2k.Cache -import java.util.concurrent.CompletableFuture - -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") ?: "tfb-database" - database = settings.databaseName - user = settings.databaseUsername - password = settings.databasePassword - cachePreparedStatements = true - } - } - - private val poolOptions: PoolOptions by lazy { - PoolOptions().apply { - val environment = Jvm.systemSettingOrNull("BENCHMARK_ENV")?.lowercase() - maxSize = 8 + if (environment == "citrine") Jvm.cpuCount else Jvm.cpuCount * 2 - } - } - - private val dataSource: SqlClient by lazy { PgPool.pool(vertx(), connectOptions, poolOptions) } - - override fun findAllFortunes(): CompletableFuture> = - dataSource.preparedQuery(SELECT_ALL_FORTUNES) - .execute() - .map { rowSet -> - rowSet.map { row -> Fortune(row.getInteger(0), row.getString(1)) } - } - .toCompletionStage() - .toCompletableFuture() - - override fun findWorlds(ids: List): CompletableFuture> { - val futures = ids.map { findWorld(it, dataSource) } - return all(futures).map { it.list() }.toCompletionStage().toCompletableFuture() - } - - override fun replaceWorlds(worlds: List): CompletableFuture<*> { - val futures = worlds.map { - val worldId = it.id - val newRandomNumber = it.randomNumber - dataSource - .preparedQuery(SELECT_WORLD) - .execute(Tuple.of(worldId)) - .flatMap { 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)) - } - } - return all(futures).toCompletionStage().toCompletableFuture() - } - - override fun initWorldsCache(cache: Cache) { - 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 = - client - .preparedQuery(SELECT_WORLD) - .execute(Tuple.of(id)) - .map { rowSet -> - val row = rowSet.iterator().next() - World(row.getInteger(0), row.getInteger(1)) - } -} From 4b41cdb94201f5d9e2a231fa13c2e01a4bd4925a Mon Sep 17 00:00:00 2001 From: jaguililla Date: Tue, 15 Aug 2023 20:03:43 +0200 Subject: [PATCH 108/149] Update dependencies --- .../Kotlin/hexagon/benchmark_config.json | 27 +++++++++++++++++-- frameworks/Kotlin/hexagon/config.toml | 20 +++++++++++++- .../hexagon-nettyepoll-native.dockerfile | 21 +++++++++++++++ 3 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 frameworks/Kotlin/hexagon/hexagon-nettyepoll-native.dockerfile diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index c98335451d2..2fa74f4babc 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -94,7 +94,7 @@ "notes": "http://hexagonkt.com", "versus": "netty" }, - "nettyepoll-async-pgclient": { + "nettyepoll-native": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -113,7 +113,7 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Netty Epoll Async PgClient", + "display_name": "Hexagon Netty Epoll Native PgClient", "notes": "http://hexagonkt.com", "versus": "netty" }, @@ -163,6 +163,29 @@ "notes": "http://hexagonkt.com", "versus": "helidon-nima" }, + "nima-native": { + "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": "Helidon", + "webserver": "None", + "os": "Linux", + "database_os": "Linux", + "display_name": "Hexagon Nima Native PostgreSQL", + "notes": "http://hexagonkt.com", + "versus": "helidon-nima" + }, "nima-pgclient": { "json_url": "/json", "db_url": "/db", diff --git a/frameworks/Kotlin/hexagon/config.toml b/frameworks/Kotlin/hexagon/config.toml index 5629b5a7d8d..d00c779ea55 100644 --- a/frameworks/Kotlin/hexagon/config.toml +++ b/frameworks/Kotlin/hexagon/config.toml @@ -73,7 +73,7 @@ platform = "Netty" webserver = "None" versus = "netty" -[nettyepoll-async-pgclient] +[nettyepoll-native] urls.plaintext = "/plaintext" urls.json = "/json" urls.db = "/db" @@ -127,6 +127,24 @@ platform = "Helidon" webserver = "None" versus = "helidon-nima" +[nima-native] +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 = "Helidon" +webserver = "None" +versus = "helidon-nima" + [nima-pgclient] urls.plaintext = "/plaintext" urls.json = "/json" diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-native.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-native.dockerfile new file mode 100644 index 00000000000..a8e9961810a --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-native.dockerfile @@ -0,0 +1,21 @@ +# +# BUILD +# +FROM ghcr.io/graalvm/native-image-community:17-ol9 as build +USER root +WORKDIR /hexagon + +ADD . . +RUN microdnf -y install findutils +RUN ./gradlew --quiet classes +RUN ./gradlew --quiet -x test nativeCompile + +# +# RUNTIME +# +FROM scratch +ARG PROJECT=hexagon_nettyepoll_postgresql + +COPY --from=build /hexagon/$PROJECT/build/native/nativeCompile/$PROJECT / + +ENTRYPOINT [ "/hexagon_nettyepoll_postgresql" ] From 82eb6345b9120f9cedf38a26dfe0b6faf4f7ebba Mon Sep 17 00:00:00 2001 From: jaguililla Date: Tue, 15 Aug 2023 20:11:52 +0200 Subject: [PATCH 109/149] Fix build --- frameworks/Kotlin/hexagon/settings.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/settings.gradle b/frameworks/Kotlin/hexagon/settings.gradle index a82f139234f..e3acf2270d5 100644 --- a/frameworks/Kotlin/hexagon/settings.gradle +++ b/frameworks/Kotlin/hexagon/settings.gradle @@ -4,7 +4,6 @@ include( "core", "store_pgclient", "store_sql", - "test", "hexagon_jetty_pgclient", "hexagon_jetty_postgresql", From d1b507b8a23ad4921ef5f2f757e3e5a29827230b Mon Sep 17 00:00:00 2001 From: jaguililla Date: Tue, 15 Aug 2023 23:31:11 +0200 Subject: [PATCH 110/149] Fix controller --- frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt index 37ab786e791..c30c1007f89 100644 --- a/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt @@ -39,8 +39,8 @@ class Controller( val path: PathHandler by lazy { path { - on("*") { send(headers = headers) } - on("*", DateCallback()) + before("*") { send(headers = headers) } + before("*", DateCallback()) get("/plaintext") { ok(textMessage, contentType = plain) } get("/json") { ok(Message(textMessage).toJson(), contentType = json) } From 5a43ee1b434cd855068d19687a42af0a460bb561 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 16 Aug 2023 16:40:48 +0200 Subject: [PATCH 111/149] Fix native tests --- .../Kotlin/hexagon/benchmark_config.json | 20 +++++++++---------- .../core/native-image.properties | 1 + ...erfile => hexagon-jetty-native.dockerfile} | 8 ++++---- .../hexagon/hexagon-nima-native.dockerfile | 4 ++-- .../native-image.properties | 1 + .../build.gradle | 1 - 6 files changed, 18 insertions(+), 17 deletions(-) rename frameworks/Kotlin/hexagon/{hexagon-nettyepoll-native.dockerfile => hexagon-jetty-native.dockerfile} (50%) create mode 100644 frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/hexagon_jetty_postgresql/native-image.properties diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index 2fa74f4babc..053d701f5ee 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -25,7 +25,7 @@ "notes": "http://hexagonkt.com", "versus": "servlet" }, - "jettyloom": { + "jetty-native": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -44,11 +44,11 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Jetty Loom PostgreSQL", + "display_name": "Hexagon Jetty Native PostgreSQL", "notes": "http://hexagonkt.com", "versus": "servlet" }, - "jettyloom-pgclient": { + "jettyloom": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -67,11 +67,11 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Jetty Loom PgClient", + "display_name": "Hexagon Jetty Loom PostgreSQL", "notes": "http://hexagonkt.com", "versus": "servlet" }, - "nettyepoll": { + "jettyloom-pgclient": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -86,15 +86,15 @@ "framework": "Hexagon", "language": "Kotlin", "orm": "Raw", - "platform": "Netty", + "platform": "Servlet", "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Netty Epoll PostgreSQL", + "display_name": "Hexagon Jetty Loom PgClient", "notes": "http://hexagonkt.com", - "versus": "netty" + "versus": "servlet" }, - "nettyepoll-native": { + "nettyepoll": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -113,7 +113,7 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Netty Epoll Native PgClient", + "display_name": "Hexagon Netty Epoll PostgreSQL", "notes": "http://hexagonkt.com", "versus": "netty" }, diff --git a/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties index ee1c0199d95..9f3cd246318 100644 --- a/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties +++ b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties @@ -2,6 +2,7 @@ Args= \ -H:IncludeResources=.*\\.(html|class) \ --enable-preview \ --static \ + --libc=musl \ --initialize-at-build-time=org.slf4j.jul.JDK14LoggerAdapter \ --initialize-at-build-time=org.slf4j.jul.JDK14LoggerAdapter$1 \ --initialize-at-build-time=org.slf4j.LoggerFactory diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-native.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile similarity index 50% rename from frameworks/Kotlin/hexagon/hexagon-nettyepoll-native.dockerfile rename to frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile index a8e9961810a..61f63ad0af8 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-native.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile @@ -1,21 +1,21 @@ # # BUILD # -FROM ghcr.io/graalvm/native-image-community:17-ol9 as build +FROM ghcr.io/graalvm/native-image-community:17-muslib-ol9 as build USER root WORKDIR /hexagon ADD . . RUN microdnf -y install findutils RUN ./gradlew --quiet classes -RUN ./gradlew --quiet -x test nativeCompile +RUN ./gradlew --quiet -x test hexagon_jetty_postgresql:nativeCompile # # RUNTIME # FROM scratch -ARG PROJECT=hexagon_nettyepoll_postgresql +ARG PROJECT=hexagon_jetty_postgresql COPY --from=build /hexagon/$PROJECT/build/native/nativeCompile/$PROJECT / -ENTRYPOINT [ "/hexagon_nettyepoll_postgresql" ] +ENTRYPOINT [ "/hexagon_jetty_postgresql" ] diff --git a/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile index 004b0dba351..5e10595efaf 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile @@ -1,14 +1,14 @@ # # BUILD # -FROM ghcr.io/graalvm/native-image-community:17-ol9 as build +FROM ghcr.io/graalvm/native-image-community:20-muslib-ol9 as build USER root WORKDIR /hexagon ADD . . RUN microdnf -y install findutils RUN ./gradlew --quiet classes -RUN ./gradlew --quiet -x test nativeCompile +RUN ./gradlew --quiet -x test hexagon_nima_postgresql:nativeCompile # # RUNTIME diff --git a/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/hexagon_jetty_postgresql/native-image.properties b/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/hexagon_jetty_postgresql/native-image.properties new file mode 100644 index 00000000000..2f30ad20d06 --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/hexagon_jetty_postgresql/native-image.properties @@ -0,0 +1 @@ +Args=-H:IncludeResources=.*\\.css diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/build.gradle b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/build.gradle index d3ce42499e4..243fa57c121 100644 --- a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/build.gradle +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/build.gradle @@ -1,5 +1,4 @@ -apply(from: "$gradleScripts/native.gradle") apply(from: "$gradleScripts/application.gradle") dependencies { From 634637c0b13a337dd5303c686656142b1d713cd6 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 17 Aug 2023 06:41:08 +0200 Subject: [PATCH 112/149] Fix native tests --- frameworks/Kotlin/hexagon/build.gradle | 2 +- .../hexagon_jetty_postgresql/native-image.properties | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/hexagon_jetty_postgresql/native-image.properties diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 669495460e6..071047a248e 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -9,7 +9,7 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.0.0" + hexagonVersion = "3.0.1" jettyVersion = "12.0.0" nettyVersion = "4.1.96.Final" diff --git a/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/hexagon_jetty_postgresql/native-image.properties b/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/hexagon_jetty_postgresql/native-image.properties deleted file mode 100644 index 2f30ad20d06..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/hexagon_jetty_postgresql/native-image.properties +++ /dev/null @@ -1 +0,0 @@ -Args=-H:IncludeResources=.*\\.css From b8be3649db5d0a698280fdcd3d166046cf2c1e2f Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sun, 20 Aug 2023 08:45:30 +0200 Subject: [PATCH 113/149] Add note --- frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt b/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt index c30c1007f89..5bfd17dfcd5 100644 --- a/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt +++ b/frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt @@ -62,6 +62,7 @@ class Controller( val fortunes = store.findAllFortunes() + Fortune(0, "Additional fortune added at request time.") val sortedFortunes = fortunes.sortedBy { it.message } val context = mapOf("fortunes" to sortedFortunes) + // TODO Pass the map with the template val body = templateAdapter.render(templateUrl, context) return ok(body, contentType = html) From 44bfbce5786158c6b8e4bcf174a6c6174f2bdb2c Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 23 Aug 2023 18:43:24 +0200 Subject: [PATCH 114/149] Add note --- frameworks/Kotlin/hexagon/build.gradle | 2 +- frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile | 2 +- .../Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon-nima.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon.dockerfile | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 071047a248e..e25721ea7bc 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,6 +1,6 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "1.9.0" apply false + id "org.jetbrains.kotlin.jvm" version "1.9.10" apply false id "org.graalvm.buildtools.native" version "0.9.24" apply false } diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile index ce47e8fcb97..88aaf007449 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.2.1-jdk17-alpine AS build +FROM docker.io/gradle:8.3-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile index 464506eb198..254f4edfe16 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.2.1-jdk17-alpine AS build +FROM docker.io/gradle:8.3-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile index 3ec94a9929d..5b120fb19eb 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.2.1-jdk17-alpine AS build +FROM docker.io/gradle:8.3-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile index 1b3c56e1823..9a07262affb 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.2.1-jdk17-alpine AS build +FROM docker.io/gradle:8.3-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile index d0db94e2eb3..6500113e675 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.2.1-jdk17-alpine AS build +FROM docker.io/gradle:8.3-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile index 18600a7beaf..7f2acab2d31 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.2.1-jdk17-alpine AS build +FROM docker.io/gradle:8.3-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index 17c6f46db85..d6b9a9e504a 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.2.1-jdk17-alpine AS build +FROM docker.io/gradle:8.3-jdk17-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index bac92f13a42..2a62cbac2ba 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.2.1-jdk17-alpine AS build +FROM docker.io/gradle:8.3-jdk17-alpine AS build USER root WORKDIR /hexagon From 10d635c350417c23d3f6344b124a652b3e6f2669 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 31 Aug 2023 18:44:25 +0200 Subject: [PATCH 115/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 8 ++++---- .../hexagon/gradle/wrapper/gradle-wrapper.jar | Bin 63375 -> 63721 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- frameworks/Kotlin/hexagon/gradlew | 3 ++- .../src/main/kotlin/Benchmark.kt | 4 ++-- .../src/main/kotlin/Benchmark.kt | 4 ++-- .../src/main/kotlin/Benchmark.kt | 4 ++-- .../src/main/kotlin/Benchmark.kt | 4 ++-- .../src/main/kotlin/WebListenerServer.kt | 4 ++-- 9 files changed, 17 insertions(+), 16 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index e25721ea7bc..9cb5a2591f3 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,7 +1,7 @@ plugins { id "org.jetbrains.kotlin.jvm" version "1.9.10" apply false - id "org.graalvm.buildtools.native" version "0.9.24" apply false + id "org.graalvm.buildtools.native" version "0.9.25" apply false } version = "1.0.0" @@ -9,13 +9,13 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.0.1" + hexagonVersion = "3.0.3" jettyVersion = "12.0.0" - nettyVersion = "4.1.96.Final" + nettyVersion = "4.1.97.Final" hikariVersion = "5.0.1" postgresqlVersion = "42.6.0" - vertxVersion = "4.4.4" + vertxVersion = "4.4.5" cache2kVersion = "2.6.1.Final" applicationClass = "com.hexagonkt.BenchmarkKt" diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar index 033e24c4cdf41af1ab109bc7f253b2b887023340..7f93135c49b765f8051ef9d0a6055ff8e46073d8 100644 GIT binary patch delta 28216 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 diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties index ab1eb5eecd1..50bed7a3fb7 100644 --- a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties +++ b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https://services.gradle.org/distributions/gradle-8.2.1-bin.zip +distributionUrl=https://services.gradle.org/distributions/gradle-8.3-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/frameworks/Kotlin/hexagon/gradlew b/frameworks/Kotlin/hexagon/gradlew index fcb6fca147c..0adc8e1a532 100755 --- a/frameworks/Kotlin/hexagon/gradlew +++ b/frameworks/Kotlin/hexagon/gradlew @@ -83,7 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/src/main/kotlin/Benchmark.kt index 983831ad866..563f89fd60b 100644 --- a/frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/src/main/kotlin/Benchmark.kt @@ -1,16 +1,16 @@ package com.hexagonkt import com.hexagonkt.core.Jvm.systemFlag +import com.hexagonkt.core.urlOf import com.hexagonkt.http.server.jetty.JettyServletAdapter import com.hexagonkt.store.BenchmarkPgClientStore import com.hexagonkt.templates.rocker.RockerAdapter -import java.net.URL fun main() { val settings = Settings() val store = BenchmarkPgClientStore("postgresql") val templateEngine = RockerAdapter() - val templateUrl = URL("classpath:fortunes.rocker.html") + val templateUrl = urlOf("classpath:fortunes.rocker.html") val engine = JettyServletAdapter( sendDateHeader = settings.sendDateHeader, sendServerVersion = settings.sendServerVersion, diff --git a/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/kotlin/Benchmark.kt index 1ba499672b8..8e39a09de63 100644 --- a/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/kotlin/Benchmark.kt @@ -1,16 +1,16 @@ package com.hexagonkt import com.hexagonkt.core.Jvm.systemFlag +import com.hexagonkt.core.urlOf import com.hexagonkt.http.server.jetty.JettyServletAdapter import com.hexagonkt.store.BenchmarkSqlStore import com.hexagonkt.templates.rocker.RockerAdapter -import java.net.URL fun main() { val settings = Settings() val store = BenchmarkSqlStore("postgresql") val templateEngine = RockerAdapter() - val templateUrl = URL("classpath:fortunes.rocker.html") + val templateUrl = urlOf("classpath:fortunes.rocker.html") val engine = JettyServletAdapter( sendDateHeader = settings.sendDateHeader, sendServerVersion = settings.sendServerVersion, diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/src/main/kotlin/Benchmark.kt index cf1cf7d998e..40bca0a1428 100644 --- a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/src/main/kotlin/Benchmark.kt @@ -1,11 +1,11 @@ package com.hexagonkt +import com.hexagonkt.core.urlOf import com.hexagonkt.http.server.netty.epoll.NettyEpollServerAdapter import com.hexagonkt.store.BenchmarkPgClientStore import com.hexagonkt.templates.rocker.RockerAdapter import io.netty.util.ResourceLeakDetector import io.netty.util.ResourceLeakDetector.Level.DISABLED -import java.net.URL fun main() { ResourceLeakDetector.setLevel(DISABLED) @@ -16,7 +16,7 @@ fun main() { val settings = Settings() val store = BenchmarkPgClientStore("postgresql") val templateEngine = RockerAdapter() - val templateUrl = URL("classpath:fortunes.rocker.html") + val templateUrl = urlOf("classpath:fortunes.rocker.html") val engine = NettyEpollServerAdapter() val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/src/main/kotlin/Benchmark.kt index dcf1495705a..6e5463e880c 100644 --- a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/src/main/kotlin/Benchmark.kt @@ -1,11 +1,11 @@ package com.hexagonkt +import com.hexagonkt.core.urlOf import com.hexagonkt.http.server.netty.epoll.NettyEpollServerAdapter import com.hexagonkt.store.BenchmarkSqlStore import com.hexagonkt.templates.rocker.RockerAdapter import io.netty.util.ResourceLeakDetector import io.netty.util.ResourceLeakDetector.Level.DISABLED -import java.net.URL fun main() { ResourceLeakDetector.setLevel(DISABLED) @@ -16,7 +16,7 @@ fun main() { val settings = Settings() val store = BenchmarkSqlStore("postgresql") val templateEngine = RockerAdapter() - val templateUrl = URL("classpath:fortunes.rocker.html") + val templateUrl = urlOf("classpath:fortunes.rocker.html") val engine = NettyEpollServerAdapter() val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) diff --git a/frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/src/main/kotlin/WebListenerServer.kt b/frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/src/main/kotlin/WebListenerServer.kt index 38a2731deee..86e43997145 100644 --- a/frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/src/main/kotlin/WebListenerServer.kt +++ b/frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/src/main/kotlin/WebListenerServer.kt @@ -1,5 +1,6 @@ package com.hexagonkt +import com.hexagonkt.core.urlOf import com.hexagonkt.http.model.Header import com.hexagonkt.http.model.Headers import com.hexagonkt.http.handlers.HttpHandler @@ -8,7 +9,6 @@ import com.hexagonkt.http.server.servlet.ServletServer import com.hexagonkt.store.BenchmarkSqlStore import com.hexagonkt.templates.rocker.RockerAdapter import jakarta.servlet.annotation.WebListener -import java.net.URL @WebListener class WebListenerServer( settings: Settings = Settings() @@ -20,7 +20,7 @@ import java.net.URL fun createHandlers(settings: Settings): List { val store = BenchmarkSqlStore("postgresql") val templateEngine = RockerAdapter() - val templateUrl = URL("classpath:fortunes.rocker.html") + val templateUrl = urlOf("classpath:fortunes.rocker.html") val controller = Controller(settings, store, templateEngine, templateUrl) val controllerPath = controller.path val serverHeaderHandler = OnHandler("*") { From 5fb9def62802fb79e14ec18090798695fc372841 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 31 Aug 2023 19:34:31 +0200 Subject: [PATCH 116/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 9cb5a2591f3..bcf7cb62aad 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -9,7 +9,7 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.0.3" + hexagonVersion = "3.0.4" jettyVersion = "12.0.0" nettyVersion = "4.1.97.Final" From d3e4007af800c4609022c910fabbab463599cf07 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sun, 3 Sep 2023 19:12:03 +0200 Subject: [PATCH 117/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index bcf7cb62aad..e89a6493bdf 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -9,7 +9,7 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.0.4" + hexagonVersion = "3.1.0" jettyVersion = "12.0.0" nettyVersion = "4.1.97.Final" From ab7c944baf227af249dc3f128cdc5995e9b51acc Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sun, 3 Sep 2023 21:36:19 +0200 Subject: [PATCH 118/149] Recheck CI jobs From d6136eb18da47ac093bf7a01e34541c727fcde0c Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 20 Sep 2023 14:05:35 +0200 Subject: [PATCH 119/149] Update dependencies --- frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile index 61f63ad0af8..3e9f700ba25 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM ghcr.io/graalvm/native-image-community:17-muslib-ol9 as build +FROM ghcr.io/graalvm/native-image-community:21-muslib-ol9 as build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile index 5e10595efaf..2b85c875894 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM ghcr.io/graalvm/native-image-community:20-muslib-ol9 as build +FROM ghcr.io/graalvm/native-image-community:21-muslib-ol9 as build USER root WORKDIR /hexagon From 6789ae5c412ecf9b9ad8b0d975b81158896dc9d9 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 20 Sep 2023 19:18:00 +0200 Subject: [PATCH 120/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 4 ++-- frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile | 6 +++--- .../Kotlin/hexagon/hexagon_nima_pgclient/build.gradle | 1 + .../Kotlin/hexagon/hexagon_nima_postgresql/build.gradle | 1 - 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index e89a6493bdf..707f7a5aabe 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,7 +1,7 @@ plugins { id "org.jetbrains.kotlin.jvm" version "1.9.10" apply false - id "org.graalvm.buildtools.native" version "0.9.25" apply false + id "org.graalvm.buildtools.native" version "0.9.27" apply false } version = "1.0.0" @@ -9,7 +9,7 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.1.0" + hexagonVersion = "3.2.0" jettyVersion = "12.0.0" nettyVersion = "4.1.97.Final" diff --git a/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile index 2b85c875894..c2a8eb1d854 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile @@ -8,14 +8,14 @@ WORKDIR /hexagon ADD . . RUN microdnf -y install findutils RUN ./gradlew --quiet classes -RUN ./gradlew --quiet -x test hexagon_nima_postgresql:nativeCompile +RUN ./gradlew --quiet -x test hexagon_nima_pgclient:nativeCompile # # RUNTIME # FROM scratch -ARG PROJECT=hexagon_nima_postgresql +ARG PROJECT=hexagon_nima_pgclient COPY --from=build /hexagon/$PROJECT/build/native/nativeCompile/$PROJECT / -ENTRYPOINT [ "/hexagon_nima_postgresql" ] +ENTRYPOINT [ "/hexagon_nima_pgclient" ] diff --git a/frameworks/Kotlin/hexagon/hexagon_nima_pgclient/build.gradle b/frameworks/Kotlin/hexagon/hexagon_nima_pgclient/build.gradle index 86d2692a326..3c08cf64bdf 100644 --- a/frameworks/Kotlin/hexagon/hexagon_nima_pgclient/build.gradle +++ b/frameworks/Kotlin/hexagon/hexagon_nima_pgclient/build.gradle @@ -1,5 +1,6 @@ apply(from: "$gradleScripts/application.gradle") +apply(from: "$gradleScripts/native.gradle") dependencies { api(project(":store_pgclient")) diff --git a/frameworks/Kotlin/hexagon/hexagon_nima_postgresql/build.gradle b/frameworks/Kotlin/hexagon/hexagon_nima_postgresql/build.gradle index 2957919e905..933b9aca630 100644 --- a/frameworks/Kotlin/hexagon/hexagon_nima_postgresql/build.gradle +++ b/frameworks/Kotlin/hexagon/hexagon_nima_postgresql/build.gradle @@ -1,6 +1,5 @@ apply(from: "$gradleScripts/application.gradle") -apply(from: "$gradleScripts/native.gradle") dependencies { api(project(":store_sql")) From b468ae955b55f923bc72e46e23f57f7d3b7f4f7c Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 20 Sep 2023 19:20:00 +0200 Subject: [PATCH 121/149] Update dependencies --- frameworks/Kotlin/hexagon/benchmark_config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index 053d701f5ee..6253c67d432 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -182,7 +182,7 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Nima Native PostgreSQL", + "display_name": "Hexagon Nima Native PgClient", "notes": "http://hexagonkt.com", "versus": "helidon-nima" }, From 5f670632be97544c89e47c2b5a1b2108c2e77420 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 20 Sep 2023 19:52:54 +0200 Subject: [PATCH 122/149] Update dependencies --- .../com.hexagonkt.benchmark/core/native-image.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties index 9f3cd246318..bd75ced503f 100644 --- a/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties +++ b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties @@ -1,5 +1,6 @@ Args= \ -H:IncludeResources=.*\\.(html|class) \ + -march=native \ --enable-preview \ --static \ --libc=musl \ From d10bbce3c2440ffb1a42894352c670535f92ef69 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 20 Sep 2023 19:57:48 +0200 Subject: [PATCH 123/149] Update dependencies --- frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon-nima.dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile index 6500113e675..9aa08a59158 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile @@ -12,7 +12,7 @@ RUN gradle --quiet -x test installDist # # RUNTIME # -FROM docker.io/eclipse-temurin:20-jre-alpine +FROM docker.io/eclipse-temurin:21-jre-alpine ARG PROJECT=hexagon_nima_pgclient ENV POSTGRESQL_DB_HOST tfb-database diff --git a/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile index 7f2acab2d31..abe8f6904b7 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile @@ -12,7 +12,7 @@ RUN gradle --quiet -x test installDist # # RUNTIME # -FROM docker.io/eclipse-temurin:20-jre-alpine +FROM docker.io/eclipse-temurin:21-jre-alpine ARG PROJECT=hexagon_nima_postgresql ENV POSTGRESQL_DB_HOST tfb-database From 7bada4527b5f9dc30eaf44fb3b84fe46f851c3ca Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 20 Oct 2023 19:48:10 +0200 Subject: [PATCH 124/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 17 ++++++++++------- frameworks/Kotlin/hexagon/core/build.gradle | 16 +++++++++------- .../core/native-image.properties | 1 - .../gradle/wrapper/gradle-wrapper.properties | 2 +- frameworks/Kotlin/hexagon/gradlew | 14 +++++++------- .../hexagon-jettyloom-pgclient.dockerfile | 4 ++-- .../Kotlin/hexagon/hexagon-jettyloom.dockerfile | 4 ++-- .../hexagon-nettyepoll-pgclient.dockerfile | 4 ++-- .../hexagon/hexagon-nettyepoll.dockerfile | 4 ++-- .../hexagon/hexagon-nima-pgclient.dockerfile | 2 +- .../Kotlin/hexagon/hexagon-nima.dockerfile | 2 +- .../Kotlin/hexagon/hexagon-tomcat.dockerfile | 4 ++-- frameworks/Kotlin/hexagon/hexagon.dockerfile | 4 ++-- .../Kotlin/hexagon/store_pgclient/build.gradle | 2 +- 14 files changed, 42 insertions(+), 38 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 707f7a5aabe..de585fb3a5b 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,7 +1,7 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "1.9.10" apply false - id "org.graalvm.buildtools.native" version "0.9.27" apply false + id "org.jetbrains.kotlin.jvm" version "1.9.20-RC" apply false + id "org.graalvm.buildtools.native" version "0.9.28" apply false } version = "1.0.0" @@ -9,18 +9,17 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.2.0" - jettyVersion = "12.0.0" - nettyVersion = "4.1.97.Final" + hexagonVersion = "3.3.1" + jettyVersion = "12.0.2" + nettyVersion = "4.1.100.Final" hikariVersion = "5.0.1" postgresqlVersion = "42.6.0" - vertxVersion = "4.4.5" + vertxVersion = "4.4.6" cache2kVersion = "2.6.1.Final" applicationClass = "com.hexagonkt.BenchmarkKt" modules = "java.naming,java.sql,java.management" - options = "--enable-preview" gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/$hexagonVersion/gradle" } @@ -29,3 +28,7 @@ subprojects { apply(from: "$gradleScripts/kotlin.gradle") } + +tasks.wrapper { + gradleVersion = "8.4" +} diff --git a/frameworks/Kotlin/hexagon/core/build.gradle b/frameworks/Kotlin/hexagon/core/build.gradle index 4cf6f44b80c..faf2a3c0484 100644 --- a/frameworks/Kotlin/hexagon/core/build.gradle +++ b/frameworks/Kotlin/hexagon/core/build.gradle @@ -1,6 +1,7 @@ plugins { - id("nu.studer.rocker") version("3.0.4") +// id("nu.studer.rocker") version("3.0.4") + id("com.fizzed.rocker") version("1.4.0") } dependencies { @@ -23,10 +24,11 @@ tasks.register("minimizeTemplate") { jar.dependsOn("minimizeTemplate") rocker { - configurations { - create("main") { - templateDir.set(file("src/main/resources")) - optimize.set(true) - } - } + classBaseDirectory = file("build") +// configurations { +// create("main") { +// templateDir.set(file("src/main/resources")) +// optimize.set(true) +// } +// } } diff --git a/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties index bd75ced503f..f42f7aed73f 100644 --- a/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties +++ b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties @@ -1,7 +1,6 @@ Args= \ -H:IncludeResources=.*\\.(html|class) \ -march=native \ - --enable-preview \ --static \ --libc=musl \ --initialize-at-build-time=org.slf4j.jul.JDK14LoggerAdapter \ diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties index 50bed7a3fb7..3fa8f862f75 100644 --- a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties +++ b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https://services.gradle.org/distributions/gradle-8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/frameworks/Kotlin/hexagon/gradlew b/frameworks/Kotlin/hexagon/gradlew index 0adc8e1a532..1aa94a42690 100755 --- a/frameworks/Kotlin/hexagon/gradlew +++ b/frameworks/Kotlin/hexagon/gradlew @@ -145,7 +145,7 @@ 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 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -153,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -202,11 +202,11 @@ fi # 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"' -# 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. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile index 88aaf007449..10f40528c0a 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.3-jdk17-alpine AS build +FROM docker.io/gradle:8.4-jdk21-alpine AS build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN gradle --quiet -x test installDist # # RUNTIME # -FROM docker.io/eclipse-temurin:20-jre-alpine +FROM docker.io/eclipse-temurin:21-jre-alpine ARG PROJECT=hexagon_jetty_pgclient ENV POSTGRESQL_DB_HOST tfb-database diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile index 254f4edfe16..ce807d1c2fe 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.3-jdk17-alpine AS build +FROM docker.io/gradle:8.4-jdk21-alpine AS build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN gradle --quiet -x test installDist # # RUNTIME # -FROM docker.io/eclipse-temurin:20-jre-alpine +FROM docker.io/eclipse-temurin:21-jre-alpine ARG PROJECT=hexagon_jetty_postgresql ENV POSTGRESQL_DB_HOST tfb-database diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile index 5b120fb19eb..d07a610bcd8 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.3-jdk17-alpine AS build +FROM docker.io/gradle:8.4-jdk21-alpine AS build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN gradle --quiet -x test installDist # # RUNTIME # -FROM docker.io/eclipse-temurin:17-jre-alpine +FROM docker.io/eclipse-temurin:21-jre-alpine ARG PROJECT=hexagon_nettyepoll_pgclient ENV POSTGRESQL_DB_HOST tfb-database diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile index 9a07262affb..c813f85bf27 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.3-jdk17-alpine AS build +FROM docker.io/gradle:8.4-jdk21-alpine AS build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN gradle --quiet -x test installDist # # RUNTIME # -FROM docker.io/eclipse-temurin:17-jre-alpine +FROM docker.io/eclipse-temurin:21-jre-alpine ARG PROJECT=hexagon_nettyepoll_postgresql ENV POSTGRESQL_DB_HOST tfb-database diff --git a/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile index 9aa08a59158..7d9d9faed8c 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.3-jdk17-alpine AS build +FROM docker.io/gradle:8.4-jdk21-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile index abe8f6904b7..69004e95386 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.3-jdk17-alpine AS build +FROM docker.io/gradle:8.4-jdk21-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index d6b9a9e504a..c28cb74d5d4 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.3-jdk17-alpine AS build +FROM docker.io/gradle:8.4-jdk21-alpine AS build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN gradle --quiet -x test war # # RUNTIME # -FROM docker.io/tomcat:10-jre17-temurin-jammy +FROM docker.io/tomcat:10-jre21-temurin-jammy ARG MODULE=/hexagon/hexagon_tomcat_postgresql ENV POSTGRESQL_DB_HOST tfb-database diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index 2a62cbac2ba..7723b0cae2d 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.3-jdk17-alpine AS build +FROM docker.io/gradle:8.4-jdk21-alpine AS build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN gradle --quiet -x test installDist # # RUNTIME # -FROM docker.io/eclipse-temurin:17-jre-alpine +FROM docker.io/eclipse-temurin:21-jre-alpine ARG PROJECT=hexagon_jetty_postgresql ENV POSTGRESQL_DB_HOST tfb-database diff --git a/frameworks/Kotlin/hexagon/store_pgclient/build.gradle b/frameworks/Kotlin/hexagon/store_pgclient/build.gradle index 6d0c88ad20e..1cce7998eb7 100644 --- a/frameworks/Kotlin/hexagon/store_pgclient/build.gradle +++ b/frameworks/Kotlin/hexagon/store_pgclient/build.gradle @@ -2,5 +2,5 @@ dependencies { api(project(":core")) implementation("io.vertx:vertx-pg-client:$vertxVersion") - implementation("com.ongres.scram:client:2.1") +// implementation("com.ongres.scram:client:2.1") } From 602a94206358ee9aa4c18e483b58b96073336ead Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 25 Oct 2023 14:11:29 +0200 Subject: [PATCH 125/149] Update Hexagon and Java version, switch templates to JTE --- frameworks/Kotlin/hexagon/README.md | 38 ------------------- .../Kotlin/hexagon/benchmark_config.json | 18 ++++----- frameworks/Kotlin/hexagon/build.gradle | 4 +- frameworks/Kotlin/hexagon/config.toml | 12 +++--- frameworks/Kotlin/hexagon/core/build.gradle | 25 ++++++------ .../core/native-image.properties | 3 -- .../core/reflect-config.json | 23 ----------- .../{fortunes.rocker.html => fortunes.jte} | 12 +++--- ...file => hexagon-helidon-native.dockerfile} | 6 +-- ...le => hexagon-helidon-pgclient.dockerfile} | 4 +- ....dockerfile => hexagon-helidon.dockerfile} | 4 +- .../build.gradle | 2 +- .../src/main/kotlin/Benchmark.kt | 11 +++--- .../build.gradle | 2 +- .../src/main/kotlin/Benchmark.kt | 18 +++++++++ .../src/main/kotlin/Benchmark.kt | 7 ++-- .../src/main/kotlin/Benchmark.kt | 7 ++-- .../src/main/kotlin/Benchmark.kt | 7 ++-- .../src/main/kotlin/Benchmark.kt | 7 ++-- .../src/main/kotlin/Benchmark.kt | 17 --------- .../src/main/kotlin/WebListenerServer.kt | 7 ++-- frameworks/Kotlin/hexagon/settings.gradle | 4 +- .../hexagon/store_pgclient/build.gradle | 1 - 23 files changed, 91 insertions(+), 148 deletions(-) delete mode 100644 frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/reflect-config.json rename frameworks/Kotlin/hexagon/core/src/main/resources/{fortunes.rocker.html => fortunes.jte} (57%) rename frameworks/Kotlin/hexagon/{hexagon-nima-native.dockerfile => hexagon-helidon-native.dockerfile} (65%) rename frameworks/Kotlin/hexagon/{hexagon-nima.dockerfile => hexagon-helidon-pgclient.dockerfile} (78%) rename frameworks/Kotlin/hexagon/{hexagon-nima-pgclient.dockerfile => hexagon-helidon.dockerfile} (78%) rename frameworks/Kotlin/hexagon/{hexagon_nima_pgclient => hexagon_helidon_pgclient}/build.gradle (70%) rename frameworks/Kotlin/hexagon/{hexagon_nima_pgclient => hexagon_helidon_pgclient}/src/main/kotlin/Benchmark.kt (50%) rename frameworks/Kotlin/hexagon/{hexagon_nima_postgresql => hexagon_helidon_postgresql}/build.gradle (61%) create mode 100644 frameworks/Kotlin/hexagon/hexagon_helidon_postgresql/src/main/kotlin/Benchmark.kt delete mode 100644 frameworks/Kotlin/hexagon/hexagon_nima_postgresql/src/main/kotlin/Benchmark.kt diff --git a/frameworks/Kotlin/hexagon/README.md b/frameworks/Kotlin/hexagon/README.md index 28397711a58..fafc6a6bbc8 100644 --- a/frameworks/Kotlin/hexagon/README.md +++ b/frameworks/Kotlin/hexagon/README.md @@ -15,41 +15,3 @@ To run the full benchmarks locally, on the project root (not this directory) exe ## Infrastructure Software Versions * [Hexagon stable version](http://hexagonkt.com) - -## Test URLs - -### Jetty - -* JSON Encoding Test: http://localhost:9090/json -* Plain Text Test: http://localhost:9090/plaintext -* Data-Store/Database Mapping Test: http://localhost:9090/db?queries=5 -* Fortunes: http://localhost:9090/fortunes -* Database updates: http://localhost:9090/update -* Database queries: http://localhost:9090/query - -### Netty - -* JSON Encoding Test: http://localhost:9090/json -* Plain Text Test: http://localhost:9090/plaintext -* Data-Store/Database Mapping Test: http://localhost:9090/db?queries=5 -* Fortunes: http://localhost:9090/fortunes -* Database updates: http://localhost:9090/update -* Database queries: http://localhost:9090/query - -### Netty Epoll - -* JSON Encoding Test: http://localhost:9090/json -* Plain Text Test: http://localhost:9090/plaintext -* Data-Store/Database Mapping Test: http://localhost:9090/db?queries=5 -* Fortunes: http://localhost:9090/fortunes -* Database updates: http://localhost:9090/update -* Database queries: http://localhost:9090/query - -### Tomcat - -* JSON Encoding Test: http://localhost:8080/json -* Plain Text Test: http://localhost:8080/plaintext -* Data-Store/Database Mapping Test: http://localhost:8080/db?queries=5 -* Fortunes: http://localhost:8080/fortunes -* Database updates: http://localhost:8080/update -* Database queries: http://localhost:8080/query diff --git a/frameworks/Kotlin/hexagon/benchmark_config.json b/frameworks/Kotlin/hexagon/benchmark_config.json index 6253c67d432..8155e24b68c 100644 --- a/frameworks/Kotlin/hexagon/benchmark_config.json +++ b/frameworks/Kotlin/hexagon/benchmark_config.json @@ -140,7 +140,7 @@ "notes": "http://hexagonkt.com", "versus": "netty" }, - "nima": { + "helidon": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -159,11 +159,11 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Nima PostgreSQL", + "display_name": "Hexagon Helidon PostgreSQL", "notes": "http://hexagonkt.com", - "versus": "helidon-nima" + "versus": "helidon-helidon" }, - "nima-native": { + "helidon-native": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -182,11 +182,11 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Nima Native PgClient", + "display_name": "Hexagon Helidon Native PgClient", "notes": "http://hexagonkt.com", - "versus": "helidon-nima" + "versus": "helidon-helidon" }, - "nima-pgclient": { + "helidon-pgclient": { "json_url": "/json", "db_url": "/db", "query_url": "/query?queries=", @@ -205,9 +205,9 @@ "webserver": "None", "os": "Linux", "database_os": "Linux", - "display_name": "Hexagon Nima PgClient", + "display_name": "Hexagon Helidon PgClient", "notes": "http://hexagonkt.com", - "versus": "helidon-nima" + "versus": "helidon-helidon" }, "tomcat": { "json_url": "/json", diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index de585fb3a5b..5378340a28f 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,6 +1,6 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "1.9.20-RC" apply false + id "org.jetbrains.kotlin.jvm" version "1.9.20-RC2" apply false id "org.graalvm.buildtools.native" version "0.9.28" apply false } @@ -9,7 +9,7 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.3.1" + hexagonVersion = "3.4.0" jettyVersion = "12.0.2" nettyVersion = "4.1.100.Final" diff --git a/frameworks/Kotlin/hexagon/config.toml b/frameworks/Kotlin/hexagon/config.toml index d00c779ea55..6f25ab27753 100644 --- a/frameworks/Kotlin/hexagon/config.toml +++ b/frameworks/Kotlin/hexagon/config.toml @@ -109,7 +109,7 @@ platform = "Netty" webserver = "None" versus = "netty" -[nima] +[helidon] urls.plaintext = "/plaintext" urls.json = "/json" urls.db = "/db" @@ -125,9 +125,9 @@ os = "Linux" orm = "Raw" platform = "Helidon" webserver = "None" -versus = "helidon-nima" +versus = "helidon-helidon" -[nima-native] +[helidon-native] urls.plaintext = "/plaintext" urls.json = "/json" urls.db = "/db" @@ -143,9 +143,9 @@ os = "Linux" orm = "Raw" platform = "Helidon" webserver = "None" -versus = "helidon-nima" +versus = "helidon-helidon" -[nima-pgclient] +[helidon-pgclient] urls.plaintext = "/plaintext" urls.json = "/json" urls.db = "/db" @@ -161,7 +161,7 @@ os = "Linux" orm = "Raw" platform = "Helidon" webserver = "None" -versus = "helidon-nima" +versus = "helidon-helidon" [tomcat] urls.plaintext = "/plaintext" diff --git a/frameworks/Kotlin/hexagon/core/build.gradle b/frameworks/Kotlin/hexagon/core/build.gradle index faf2a3c0484..0e96eba0f34 100644 --- a/frameworks/Kotlin/hexagon/core/build.gradle +++ b/frameworks/Kotlin/hexagon/core/build.gradle @@ -1,21 +1,21 @@ plugins { -// id("nu.studer.rocker") version("3.0.4") - id("com.fizzed.rocker") version("1.4.0") + id("gg.jte.gradle") version("3.1.3") } dependencies { api(project(":model")) api("com.hexagonkt:http_server:$hexagonVersion") - api("com.hexagonkt:templates_rocker:$hexagonVersion") - api("com.hexagonkt:logging_slf4j_jul:$hexagonVersion") + api("com.hexagonkt:templates_jte:$hexagonVersion") api("com.hexagonkt:serialization_jackson_json:$hexagonVersion") api("org.cache2k:cache2k-core:$cache2kVersion") + + jteGenerate("gg.jte:jte-native-resources:3.1.3") } tasks.register("minimizeTemplate") { doLast { - File template = file("$buildDir/resources/main/fortunes.rocker.html") + File template = file("$buildDir/resources/main/fortunes.jte") List lines = template.readLines().collect { it.trim() } template.write(lines.join("")) } @@ -23,12 +23,11 @@ tasks.register("minimizeTemplate") { jar.dependsOn("minimizeTemplate") -rocker { - classBaseDirectory = file("build") -// configurations { -// create("main") { -// templateDir.set(file("src/main/resources")) -// optimize.set(true) -// } -// } +jte { + sourceDirectory.set(file("src/main/resources").toPath()) + targetDirectory.set(file("build/classes/kotlin/main").toPath()) + + jteExtension("gg.jte.nativeimage.NativeResourcesExtension") + + generate() } diff --git a/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties index f42f7aed73f..4dac65fae39 100644 --- a/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties +++ b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties @@ -1,8 +1,5 @@ Args= \ - -H:IncludeResources=.*\\.(html|class) \ -march=native \ --static \ --libc=musl \ - --initialize-at-build-time=org.slf4j.jul.JDK14LoggerAdapter \ - --initialize-at-build-time=org.slf4j.jul.JDK14LoggerAdapter$1 \ --initialize-at-build-time=org.slf4j.LoggerFactory diff --git a/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/reflect-config.json b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/reflect-config.json deleted file mode 100644 index 11815306be2..00000000000 --- a/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/reflect-config.json +++ /dev/null @@ -1,23 +0,0 @@ -[ - { - "name": "fortunes", - "allPublicMethods": true, - "allDeclaredFields": true, - "allDeclaredMethods": true, - "allDeclaredConstructors": true - }, - { - "name": "fortunes$Template", - "allPublicMethods": true, - "allDeclaredFields": true, - "allDeclaredMethods": true, - "allDeclaredConstructors": true - }, - { - "name": "fortunes$PlainText", - "allPublicMethods": true, - "allDeclaredFields": true, - "allDeclaredMethods": true, - "allDeclaredConstructors": true - } -] diff --git a/frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.rocker.html b/frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.jte similarity index 57% rename from frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.rocker.html rename to frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.jte index c9a9d4037e5..82b28ce94c3 100644 --- a/frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.rocker.html +++ b/frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.jte @@ -1,6 +1,8 @@ @import java.util.* @import com.hexagonkt.model.Fortune -@args(Map context) + +@param List fortunes + @@ -13,12 +15,12 @@ id message - @for ((fortune) : (Collection)context.get("fortunes")) { + @for(var fortune : fortunes) - @fortune.getId() - @fortune.getMessage() + ${fortune.getId()} + ${fortune.getMessage()} - } + @endfor diff --git a/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile b/frameworks/Kotlin/hexagon/hexagon-helidon-native.dockerfile similarity index 65% rename from frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile rename to frameworks/Kotlin/hexagon/hexagon-helidon-native.dockerfile index c2a8eb1d854..54ddbfc48c4 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nima-native.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-helidon-native.dockerfile @@ -8,14 +8,14 @@ WORKDIR /hexagon ADD . . RUN microdnf -y install findutils RUN ./gradlew --quiet classes -RUN ./gradlew --quiet -x test hexagon_nima_pgclient:nativeCompile +RUN ./gradlew --quiet -x test hexagon_helidon_pgclient:nativeCompile # # RUNTIME # FROM scratch -ARG PROJECT=hexagon_nima_pgclient +ARG PROJECT=hexagon_helidon_pgclient COPY --from=build /hexagon/$PROJECT/build/native/nativeCompile/$PROJECT / -ENTRYPOINT [ "/hexagon_nima_pgclient" ] +ENTRYPOINT [ "/hexagon_helidon_pgclient" ] diff --git a/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile b/frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile similarity index 78% rename from frameworks/Kotlin/hexagon/hexagon-nima.dockerfile rename to frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile index 69004e95386..0ecb7488d43 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nima.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile @@ -13,11 +13,11 @@ RUN gradle --quiet -x test installDist # RUNTIME # FROM docker.io/eclipse-temurin:21-jre-alpine -ARG PROJECT=hexagon_nima_postgresql +ARG PROJECT=hexagon_helidon_pgclient ENV POSTGRESQL_DB_HOST tfb-database ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT -ENTRYPOINT [ "/opt/hexagon_nima_postgresql/bin/hexagon_nima_postgresql" ] +ENTRYPOINT [ "/opt/hexagon_helidon_pgclient/bin/hexagon_helidon_pgclient" ] diff --git a/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile similarity index 78% rename from frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile rename to frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile index 7d9d9faed8c..5c790a00c72 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nima-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile @@ -13,11 +13,11 @@ RUN gradle --quiet -x test installDist # RUNTIME # FROM docker.io/eclipse-temurin:21-jre-alpine -ARG PROJECT=hexagon_nima_pgclient +ARG PROJECT=hexagon_helidon_postgresql ENV POSTGRESQL_DB_HOST tfb-database ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT -ENTRYPOINT [ "/opt/hexagon_nima_pgclient/bin/hexagon_nima_pgclient" ] +ENTRYPOINT [ "/opt/hexagon_helidon_postgresql/bin/hexagon_helidon_postgresql" ] diff --git a/frameworks/Kotlin/hexagon/hexagon_nima_pgclient/build.gradle b/frameworks/Kotlin/hexagon/hexagon_helidon_pgclient/build.gradle similarity index 70% rename from frameworks/Kotlin/hexagon/hexagon_nima_pgclient/build.gradle rename to frameworks/Kotlin/hexagon/hexagon_helidon_pgclient/build.gradle index 3c08cf64bdf..5e64c7bde3f 100644 --- a/frameworks/Kotlin/hexagon/hexagon_nima_pgclient/build.gradle +++ b/frameworks/Kotlin/hexagon/hexagon_helidon_pgclient/build.gradle @@ -4,5 +4,5 @@ apply(from: "$gradleScripts/native.gradle") dependencies { api(project(":store_pgclient")) - api("com.hexagonkt:http_server_nima:$hexagonVersion") + api("com.hexagonkt:http_server_helidon:$hexagonVersion") } diff --git a/frameworks/Kotlin/hexagon/hexagon_nima_pgclient/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_helidon_pgclient/src/main/kotlin/Benchmark.kt similarity index 50% rename from frameworks/Kotlin/hexagon/hexagon_nima_pgclient/src/main/kotlin/Benchmark.kt rename to frameworks/Kotlin/hexagon/hexagon_helidon_pgclient/src/main/kotlin/Benchmark.kt index 9df2914829b..d38d33281f8 100644 --- a/frameworks/Kotlin/hexagon/hexagon_nima_pgclient/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/hexagon_helidon_pgclient/src/main/kotlin/Benchmark.kt @@ -1,16 +1,17 @@ package com.hexagonkt +import com.hexagonkt.core.media.TEXT_HTML import com.hexagonkt.core.urlOf -import com.hexagonkt.http.server.nima.NimaServerAdapter +import com.hexagonkt.http.server.helidon.HelidonServerAdapter import com.hexagonkt.store.BenchmarkPgClientStore -import com.hexagonkt.templates.rocker.RockerAdapter +import com.hexagonkt.templates.jte.JteAdapter fun main() { val settings = Settings() val store = BenchmarkPgClientStore("postgresql") - val templateEngine = RockerAdapter() - val templateUrl = urlOf("classpath:fortunes.rocker.html") - val engine = NimaServerAdapter() + val templateEngine = JteAdapter(TEXT_HTML, precompiled = true) + val templateUrl = urlOf("classpath:fortunes.jte") + val engine = HelidonServerAdapter() val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) benchmark.server.start() diff --git a/frameworks/Kotlin/hexagon/hexagon_nima_postgresql/build.gradle b/frameworks/Kotlin/hexagon/hexagon_helidon_postgresql/build.gradle similarity index 61% rename from frameworks/Kotlin/hexagon/hexagon_nima_postgresql/build.gradle rename to frameworks/Kotlin/hexagon/hexagon_helidon_postgresql/build.gradle index 933b9aca630..1fb3fbffab6 100644 --- a/frameworks/Kotlin/hexagon/hexagon_nima_postgresql/build.gradle +++ b/frameworks/Kotlin/hexagon/hexagon_helidon_postgresql/build.gradle @@ -3,5 +3,5 @@ apply(from: "$gradleScripts/application.gradle") dependencies { api(project(":store_sql")) - api("com.hexagonkt:http_server_nima:$hexagonVersion") + api("com.hexagonkt:http_server_helidon:$hexagonVersion") } diff --git a/frameworks/Kotlin/hexagon/hexagon_helidon_postgresql/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_helidon_postgresql/src/main/kotlin/Benchmark.kt new file mode 100644 index 00000000000..cbfb372cbd5 --- /dev/null +++ b/frameworks/Kotlin/hexagon/hexagon_helidon_postgresql/src/main/kotlin/Benchmark.kt @@ -0,0 +1,18 @@ +package com.hexagonkt + +import com.hexagonkt.core.media.TEXT_HTML +import com.hexagonkt.core.urlOf +import com.hexagonkt.http.server.helidon.HelidonServerAdapter +import com.hexagonkt.store.BenchmarkSqlStore +import com.hexagonkt.templates.jte.JteAdapter + +fun main() { + val settings = Settings() + val store = BenchmarkSqlStore("postgresql") + val templateEngine = JteAdapter(TEXT_HTML, precompiled = true) + val templateUrl = urlOf("classpath:fortunes.jte") + val engine = HelidonServerAdapter() + + val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) + benchmark.server.start() +} diff --git a/frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/src/main/kotlin/Benchmark.kt index 563f89fd60b..c6e8dbcf855 100644 --- a/frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/src/main/kotlin/Benchmark.kt @@ -1,16 +1,17 @@ package com.hexagonkt import com.hexagonkt.core.Jvm.systemFlag +import com.hexagonkt.core.media.TEXT_HTML import com.hexagonkt.core.urlOf import com.hexagonkt.http.server.jetty.JettyServletAdapter import com.hexagonkt.store.BenchmarkPgClientStore -import com.hexagonkt.templates.rocker.RockerAdapter +import com.hexagonkt.templates.jte.JteAdapter fun main() { val settings = Settings() val store = BenchmarkPgClientStore("postgresql") - val templateEngine = RockerAdapter() - val templateUrl = urlOf("classpath:fortunes.rocker.html") + val templateEngine = JteAdapter(TEXT_HTML, precompiled = true) + val templateUrl = urlOf("classpath:fortunes.jte") val engine = JettyServletAdapter( sendDateHeader = settings.sendDateHeader, sendServerVersion = settings.sendServerVersion, diff --git a/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/kotlin/Benchmark.kt index 8e39a09de63..64585b785b6 100644 --- a/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/kotlin/Benchmark.kt @@ -1,16 +1,17 @@ package com.hexagonkt import com.hexagonkt.core.Jvm.systemFlag +import com.hexagonkt.core.media.TEXT_HTML import com.hexagonkt.core.urlOf import com.hexagonkt.http.server.jetty.JettyServletAdapter import com.hexagonkt.store.BenchmarkSqlStore -import com.hexagonkt.templates.rocker.RockerAdapter +import com.hexagonkt.templates.jte.JteAdapter fun main() { val settings = Settings() val store = BenchmarkSqlStore("postgresql") - val templateEngine = RockerAdapter() - val templateUrl = urlOf("classpath:fortunes.rocker.html") + val templateEngine = JteAdapter(TEXT_HTML, precompiled = true) + val templateUrl = urlOf("classpath:fortunes.jte") val engine = JettyServletAdapter( sendDateHeader = settings.sendDateHeader, sendServerVersion = settings.sendServerVersion, diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/src/main/kotlin/Benchmark.kt index 40bca0a1428..5210e59e3c8 100644 --- a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/src/main/kotlin/Benchmark.kt @@ -1,9 +1,10 @@ package com.hexagonkt +import com.hexagonkt.core.media.TEXT_HTML import com.hexagonkt.core.urlOf import com.hexagonkt.http.server.netty.epoll.NettyEpollServerAdapter import com.hexagonkt.store.BenchmarkPgClientStore -import com.hexagonkt.templates.rocker.RockerAdapter +import com.hexagonkt.templates.jte.JteAdapter import io.netty.util.ResourceLeakDetector import io.netty.util.ResourceLeakDetector.Level.DISABLED @@ -15,8 +16,8 @@ fun main() { val settings = Settings() val store = BenchmarkPgClientStore("postgresql") - val templateEngine = RockerAdapter() - val templateUrl = urlOf("classpath:fortunes.rocker.html") + val templateEngine = JteAdapter(TEXT_HTML, precompiled = true) + val templateUrl = urlOf("classpath:fortunes.jte") val engine = NettyEpollServerAdapter() val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/src/main/kotlin/Benchmark.kt index 6e5463e880c..c2833552a2b 100644 --- a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/src/main/kotlin/Benchmark.kt @@ -1,9 +1,10 @@ package com.hexagonkt +import com.hexagonkt.core.media.TEXT_HTML import com.hexagonkt.core.urlOf import com.hexagonkt.http.server.netty.epoll.NettyEpollServerAdapter import com.hexagonkt.store.BenchmarkSqlStore -import com.hexagonkt.templates.rocker.RockerAdapter +import com.hexagonkt.templates.jte.JteAdapter import io.netty.util.ResourceLeakDetector import io.netty.util.ResourceLeakDetector.Level.DISABLED @@ -15,8 +16,8 @@ fun main() { val settings = Settings() val store = BenchmarkSqlStore("postgresql") - val templateEngine = RockerAdapter() - val templateUrl = urlOf("classpath:fortunes.rocker.html") + val templateEngine = JteAdapter(TEXT_HTML, precompiled = true) + val templateUrl = urlOf("classpath:fortunes.jte") val engine = NettyEpollServerAdapter() val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) diff --git a/frameworks/Kotlin/hexagon/hexagon_nima_postgresql/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_nima_postgresql/src/main/kotlin/Benchmark.kt deleted file mode 100644 index 16e4797e37a..00000000000 --- a/frameworks/Kotlin/hexagon/hexagon_nima_postgresql/src/main/kotlin/Benchmark.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.hexagonkt - -import com.hexagonkt.core.urlOf -import com.hexagonkt.http.server.nima.NimaServerAdapter -import com.hexagonkt.store.BenchmarkSqlStore -import com.hexagonkt.templates.rocker.RockerAdapter - -fun main() { - val settings = Settings() - val store = BenchmarkSqlStore("postgresql") - val templateEngine = RockerAdapter() - val templateUrl = urlOf("classpath:fortunes.rocker.html") - val engine = NimaServerAdapter() - - val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) - benchmark.server.start() -} diff --git a/frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/src/main/kotlin/WebListenerServer.kt b/frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/src/main/kotlin/WebListenerServer.kt index 86e43997145..69fe6d13ba6 100644 --- a/frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/src/main/kotlin/WebListenerServer.kt +++ b/frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/src/main/kotlin/WebListenerServer.kt @@ -1,5 +1,6 @@ package com.hexagonkt +import com.hexagonkt.core.media.TEXT_HTML import com.hexagonkt.core.urlOf import com.hexagonkt.http.model.Header import com.hexagonkt.http.model.Headers @@ -7,7 +8,7 @@ import com.hexagonkt.http.handlers.HttpHandler import com.hexagonkt.http.handlers.OnHandler import com.hexagonkt.http.server.servlet.ServletServer import com.hexagonkt.store.BenchmarkSqlStore -import com.hexagonkt.templates.rocker.RockerAdapter +import com.hexagonkt.templates.jte.JteAdapter import jakarta.servlet.annotation.WebListener @WebListener class WebListenerServer( @@ -19,8 +20,8 @@ import jakarta.servlet.annotation.WebListener fun createHandlers(settings: Settings): List { val store = BenchmarkSqlStore("postgresql") - val templateEngine = RockerAdapter() - val templateUrl = urlOf("classpath:fortunes.rocker.html") + val templateEngine = JteAdapter(TEXT_HTML, precompiled = true) + val templateUrl = urlOf("classpath:fortunes.jte") val controller = Controller(settings, store, templateEngine, templateUrl) val controllerPath = controller.path val serverHeaderHandler = OnHandler("*") { diff --git a/frameworks/Kotlin/hexagon/settings.gradle b/frameworks/Kotlin/hexagon/settings.gradle index e3acf2270d5..f7b97fb2582 100644 --- a/frameworks/Kotlin/hexagon/settings.gradle +++ b/frameworks/Kotlin/hexagon/settings.gradle @@ -7,8 +7,8 @@ include( "hexagon_jetty_pgclient", "hexagon_jetty_postgresql", - "hexagon_nima_pgclient", - "hexagon_nima_postgresql", + "hexagon_helidon_pgclient", + "hexagon_helidon_postgresql", "hexagon_nettyepoll_pgclient", "hexagon_nettyepoll_postgresql", "hexagon_tomcat_postgresql", diff --git a/frameworks/Kotlin/hexagon/store_pgclient/build.gradle b/frameworks/Kotlin/hexagon/store_pgclient/build.gradle index 1cce7998eb7..101c965aa6b 100644 --- a/frameworks/Kotlin/hexagon/store_pgclient/build.gradle +++ b/frameworks/Kotlin/hexagon/store_pgclient/build.gradle @@ -2,5 +2,4 @@ dependencies { api(project(":core")) implementation("io.vertx:vertx-pg-client:$vertxVersion") -// implementation("com.ongres.scram:client:2.1") } From ba4ddfb4d93bdda68009c1cb77aba2577712acd2 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sun, 5 Nov 2023 12:37:49 +0100 Subject: [PATCH 126/149] Update Hexagon and improve Netty Epoll configuration --- frameworks/Kotlin/hexagon/build.gradle | 8 ++++---- frameworks/Kotlin/hexagon/core/build.gradle | 4 ++-- .../src/main/kotlin/Benchmark.kt | 7 ++++++- .../src/main/kotlin/Benchmark.kt | 7 ++++++- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 5378340a28f..06489534605 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,6 +1,6 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "1.9.20-RC2" apply false + id "org.jetbrains.kotlin.jvm" version "1.9.20" apply false id "org.graalvm.buildtools.native" version "0.9.28" apply false } @@ -9,11 +9,11 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.4.0" - jettyVersion = "12.0.2" + hexagonVersion = "3.4.3" + jettyVersion = "12.0.3" nettyVersion = "4.1.100.Final" - hikariVersion = "5.0.1" + hikariVersion = "5.1.0" postgresqlVersion = "42.6.0" vertxVersion = "4.4.6" cache2kVersion = "2.6.1.Final" diff --git a/frameworks/Kotlin/hexagon/core/build.gradle b/frameworks/Kotlin/hexagon/core/build.gradle index 0e96eba0f34..18212db6bee 100644 --- a/frameworks/Kotlin/hexagon/core/build.gradle +++ b/frameworks/Kotlin/hexagon/core/build.gradle @@ -1,6 +1,6 @@ plugins { - id("gg.jte.gradle") version("3.1.3") + id("gg.jte.gradle") version("3.1.4") } dependencies { @@ -10,7 +10,7 @@ dependencies { api("com.hexagonkt:serialization_jackson_json:$hexagonVersion") api("org.cache2k:cache2k-core:$cache2kVersion") - jteGenerate("gg.jte:jte-native-resources:3.1.3") + jteGenerate("gg.jte:jte-native-resources:3.1.4") } tasks.register("minimizeTemplate") { diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/src/main/kotlin/Benchmark.kt index 5210e59e3c8..0bbd8038edd 100644 --- a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/src/main/kotlin/Benchmark.kt @@ -18,7 +18,12 @@ fun main() { val store = BenchmarkPgClientStore("postgresql") val templateEngine = JteAdapter(TEXT_HTML, precompiled = true) val templateUrl = urlOf("classpath:fortunes.jte") - val engine = NettyEpollServerAdapter() + val engine = NettyEpollServerAdapter( + keepAliveHandler = false, + httpAggregatorHandler = false, + chunkedHandler = false, + enableWebsockets = false, + ) val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) benchmark.server.start() diff --git a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/src/main/kotlin/Benchmark.kt index c2833552a2b..77fa370b915 100644 --- a/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/src/main/kotlin/Benchmark.kt @@ -18,7 +18,12 @@ fun main() { val store = BenchmarkSqlStore("postgresql") val templateEngine = JteAdapter(TEXT_HTML, precompiled = true) val templateUrl = urlOf("classpath:fortunes.jte") - val engine = NettyEpollServerAdapter() + val engine = NettyEpollServerAdapter( + keepAliveHandler = false, + httpAggregatorHandler = false, + chunkedHandler = false, + enableWebsockets = false, + ) val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) benchmark.server.start() From 5f2e20cc0c5d22af390d54a53a68bf826d7d8a75 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Mon, 20 Nov 2023 19:22:03 +0100 Subject: [PATCH 127/149] Update Hexagon version --- frameworks/Kotlin/hexagon/build.gradle | 8 ++++---- .../hexagon/gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 06489534605..9594fa16bd1 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,6 +1,6 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "1.9.20" apply false + id "org.jetbrains.kotlin.jvm" version "2.0.0-Beta1" apply false id "org.graalvm.buildtools.native" version "0.9.28" apply false } @@ -11,11 +11,11 @@ group = "com.hexagonkt" ext { hexagonVersion = "3.4.3" jettyVersion = "12.0.3" - nettyVersion = "4.1.100.Final" + nettyVersion = "4.1.101.Final" hikariVersion = "5.1.0" postgresqlVersion = "42.6.0" - vertxVersion = "4.4.6" + vertxVersion = "4.5.0" cache2kVersion = "2.6.1.Final" applicationClass = "com.hexagonkt.BenchmarkKt" @@ -30,5 +30,5 @@ subprojects { } tasks.wrapper { - gradleVersion = "8.4" + gradleVersion = "8.5-rc-3" } diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties index 3fa8f862f75..9aaaf603dda 100644 --- a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties +++ b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-rc-3-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 8ebe6778ea8b61b3b4592ceaec288ae57f5127ee Mon Sep 17 00:00:00 2001 From: jaguililla Date: Mon, 20 Nov 2023 21:05:09 +0100 Subject: [PATCH 128/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 2 +- .../hexagon/gradle/wrapper/gradle-wrapper.jar | Bin 63721 -> 43462 bytes .../hexagon/hexagon-helidon-native.dockerfile | 2 +- .../hexagon/hexagon-jetty-native.dockerfile | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 9594fa16bd1..579802375ba 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -14,7 +14,7 @@ ext { nettyVersion = "4.1.101.Final" hikariVersion = "5.1.0" - postgresqlVersion = "42.6.0" + postgresqlVersion = "42.7.0" vertxVersion = "4.5.0" cache2kVersion = "2.6.1.Final" diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar index 7f93135c49b765f8051ef9d0a6055ff8e46073d8..d64cd4917707c1f8861d8cb53dd15194d4248596 100644 GIT binary patch literal 43462 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 literal 63721 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鯊%1Et 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⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc diff --git a/frameworks/Kotlin/hexagon/hexagon-helidon-native.dockerfile b/frameworks/Kotlin/hexagon/hexagon-helidon-native.dockerfile index 54ddbfc48c4..47878fcbd28 100644 --- a/frameworks/Kotlin/hexagon/hexagon-helidon-native.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-helidon-native.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM ghcr.io/graalvm/native-image-community:21-muslib-ol9 as build +FROM ghcr.io/graalvm/native-image:21-muslib-ol9 as build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile index 3e9f700ba25..04f18158f95 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM ghcr.io/graalvm/native-image-community:21-muslib-ol9 as build +FROM ghcr.io/graalvm/native-image:21-muslib-ol9 as build USER root WORKDIR /hexagon From aa33b660ae04c0d4766a651c74b2185a137a0af5 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Mon, 20 Nov 2023 22:39:22 +0100 Subject: [PATCH 129/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 23 +++++++++++++++++++ .../hexagon/hexagon-helidon-native.dockerfile | 2 +- .../hexagon/hexagon-jetty-native.dockerfile | 2 +- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 579802375ba..ac7e99cedd8 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -32,3 +32,26 @@ subprojects { tasks.wrapper { gradleVersion = "8.5-rc-3" } + +//extensions.configure { +// fun option(name: String, value: (String) -> String): String? = +// getProperty(name)?.let(value) +// +// binaries { +// named("main") { +// listOfNotNull( +// option("static") { "--static" }, +// option("enableMonitoring") { "--enable-monitoring" }, +// option("pgoInstrument") { "--pgo-instrument" }, +// option("pgo") { "--pgo=../../../default.iprof" }, +// ) +// .forEach(buildArgs::add) +// } +// named("test") { +// listOfNotNull( +// option("pgoInstrument") { "--pgo-instrument" }, +// ) +// .forEach(buildArgs::add) +// } +// } +//} diff --git a/frameworks/Kotlin/hexagon/hexagon-helidon-native.dockerfile b/frameworks/Kotlin/hexagon/hexagon-helidon-native.dockerfile index 47878fcbd28..c402f0ee792 100644 --- a/frameworks/Kotlin/hexagon/hexagon-helidon-native.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-helidon-native.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM ghcr.io/graalvm/native-image:21-muslib-ol9 as build +FROM container-registry.oracle.com/graalvm/native-image:21-muslib-ol9 as build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile index 04f18158f95..2919fdba8b7 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM ghcr.io/graalvm/native-image:21-muslib-ol9 as build +FROM container-registry.oracle.com/graalvm/native-image:21-muslib-ol9 as build USER root WORKDIR /hexagon From 654e3d9905de3e3a5f277cc1d8874c2ce222ac7c Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 22 Nov 2023 20:33:49 +0100 Subject: [PATCH 130/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 23 ------------------- .../core/native-image.properties | 7 +++++- 2 files changed, 6 insertions(+), 24 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index ac7e99cedd8..579802375ba 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -32,26 +32,3 @@ subprojects { tasks.wrapper { gradleVersion = "8.5-rc-3" } - -//extensions.configure { -// fun option(name: String, value: (String) -> String): String? = -// getProperty(name)?.let(value) -// -// binaries { -// named("main") { -// listOfNotNull( -// option("static") { "--static" }, -// option("enableMonitoring") { "--enable-monitoring" }, -// option("pgoInstrument") { "--pgo-instrument" }, -// option("pgo") { "--pgo=../../../default.iprof" }, -// ) -// .forEach(buildArgs::add) -// } -// named("test") { -// listOfNotNull( -// option("pgoInstrument") { "--pgo-instrument" }, -// ) -// .forEach(buildArgs::add) -// } -// } -//} diff --git a/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties index 4dac65fae39..334a2820107 100644 --- a/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties +++ b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties @@ -2,4 +2,9 @@ Args= \ -march=native \ --static \ --libc=musl \ - --initialize-at-build-time=org.slf4j.LoggerFactory + --gc=G1 \ + --enable-sbom \ + --strict-image-heap \ + --initialize-at-build-time=kotlin.SynchronizedLazyImpl \ + --initialize-at-build-time=kotlin.UNINITIALIZED_VALUE \ + --initialize-at-build-time=com.hexagonkt.core.ClasspathHandler$classLoader$2 From f4dd53423eb7654d0deed6985fb60bc7bbd7ea9d Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 22 Nov 2023 22:54:58 +0100 Subject: [PATCH 131/149] Update dependencies --- .../com.hexagonkt.benchmark/core/native-image.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties index 334a2820107..58437b0f63c 100644 --- a/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties +++ b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties @@ -7,4 +7,6 @@ Args= \ --strict-image-heap \ --initialize-at-build-time=kotlin.SynchronizedLazyImpl \ --initialize-at-build-time=kotlin.UNINITIALIZED_VALUE \ - --initialize-at-build-time=com.hexagonkt.core.ClasspathHandler$classLoader$2 + --initialize-at-build-time=com.hexagonkt.core.ClasspathHandler$classLoader$2 \ + --initialize-at-build-time=org.slf4j.helpers.NOPLogger \ + --initialize-at-build-time=org.slf4j.helpers.NOPLoggerFactory From 626ee0df99fdabece0686b0e70090b51200a8e8d Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 23 Nov 2023 20:33:33 +0100 Subject: [PATCH 132/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 579802375ba..2d47ed021d9 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,6 +1,6 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "2.0.0-Beta1" apply false + id "org.jetbrains.kotlin.jvm" version "1.9.21" apply false id "org.graalvm.buildtools.native" version "0.9.28" apply false } From b43eaed09608c05bf6aae706a110f0f0037f3c7b Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sat, 2 Dec 2023 13:32:16 +0100 Subject: [PATCH 133/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 4 ++-- .../Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 2d47ed021d9..731e4d3c5e7 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -9,7 +9,7 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.4.3" + hexagonVersion = "3.4.4" jettyVersion = "12.0.3" nettyVersion = "4.1.101.Final" @@ -30,5 +30,5 @@ subprojects { } tasks.wrapper { - gradleVersion = "8.5-rc-3" + gradleVersion = "8.5" } diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties index 9aaaf603dda..1af9e0930b8 100644 --- a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties +++ b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-rc-3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 69752f34ba6ecca522262d4d1f917dbf6dbb69f8 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sat, 2 Dec 2023 16:11:55 +0100 Subject: [PATCH 134/149] Update dependencies --- .../com.hexagonkt.benchmark/core/native-image.properties | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties index 58437b0f63c..3c802071a99 100644 --- a/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties +++ b/frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties @@ -3,10 +3,4 @@ Args= \ --static \ --libc=musl \ --gc=G1 \ - --enable-sbom \ - --strict-image-heap \ - --initialize-at-build-time=kotlin.SynchronizedLazyImpl \ - --initialize-at-build-time=kotlin.UNINITIALIZED_VALUE \ - --initialize-at-build-time=com.hexagonkt.core.ClasspathHandler$classLoader$2 \ - --initialize-at-build-time=org.slf4j.helpers.NOPLogger \ - --initialize-at-build-time=org.slf4j.helpers.NOPLoggerFactory + --enable-sbom From 22c6eac22c4d179eb2492f0aa36526517a347010 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 7 Dec 2023 17:50:55 +0100 Subject: [PATCH 135/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 731e4d3c5e7..e82ca30814f 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -9,12 +9,12 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.4.4" - jettyVersion = "12.0.3" + hexagonVersion = "3.4.5" + jettyVersion = "12.0.4" nettyVersion = "4.1.101.Final" hikariVersion = "5.1.0" - postgresqlVersion = "42.7.0" + postgresqlVersion = "42.7.1" vertxVersion = "4.5.0" cache2kVersion = "2.6.1.Final" From 5c8f881cf4333a8c1c307fbcda62d8e1033f97dd Mon Sep 17 00:00:00 2001 From: jaguililla Date: Tue, 9 Jan 2024 20:25:51 +0100 Subject: [PATCH 136/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index e82ca30814f..2c70f2ed07b 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,6 +1,6 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "1.9.21" apply false + id "org.jetbrains.kotlin.jvm" version "1.9.22" apply false id "org.graalvm.buildtools.native" version "0.9.28" apply false } @@ -9,13 +9,13 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.4.5" - jettyVersion = "12.0.4" - nettyVersion = "4.1.101.Final" + hexagonVersion = "3.4.6" + jettyVersion = "12.0.5" + nettyVersion = "4.1.104.Final" hikariVersion = "5.1.0" postgresqlVersion = "42.7.1" - vertxVersion = "4.5.0" + vertxVersion = "4.5.1" cache2kVersion = "2.6.1.Final" applicationClass = "com.hexagonkt.BenchmarkKt" From dd4d49e54e9b684c486561ec97040d916ad082b8 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 22 Feb 2024 18:26:19 +0100 Subject: [PATCH 137/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 12 ++++++------ .../hexagon/gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 2c70f2ed07b..3debf65bace 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,7 +1,7 @@ plugins { id "org.jetbrains.kotlin.jvm" version "1.9.22" apply false - id "org.graalvm.buildtools.native" version "0.9.28" apply false + id "org.graalvm.buildtools.native" version "0.10.1" apply false } version = "1.0.0" @@ -9,13 +9,13 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.4.6" + hexagonVersion = "3.4.7" jettyVersion = "12.0.5" - nettyVersion = "4.1.104.Final" + nettyVersion = "4.1.107.Final" hikariVersion = "5.1.0" - postgresqlVersion = "42.7.1" - vertxVersion = "4.5.1" + postgresqlVersion = "42.7.2" + vertxVersion = "4.5.3" cache2kVersion = "2.6.1.Final" applicationClass = "com.hexagonkt.BenchmarkKt" @@ -30,5 +30,5 @@ subprojects { } tasks.wrapper { - gradleVersion = "8.5" + gradleVersion = "8.6" } diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties index 1af9e0930b8..a80b22ce5cf 100644 --- a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties +++ b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 0cec4c592fea0034b5dc331a6fe3a8c8aff30376 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 1 Mar 2024 20:29:01 +0100 Subject: [PATCH 138/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 2 +- frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile | 2 +- .../Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile | 2 +- frameworks/Kotlin/hexagon/hexagon.dockerfile | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 3debf65bace..9714488c038 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -9,7 +9,7 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.4.7" + hexagonVersion = "3.5.0" jettyVersion = "12.0.5" nettyVersion = "4.1.107.Final" diff --git a/frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile index 0ecb7488d43..d87e78307b0 100644 --- a/frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.4-jdk21-alpine AS build +FROM docker.io/gradle:8.6-jdk21-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile b/frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile index 5c790a00c72..913a9459a06 100644 --- a/frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.4-jdk21-alpine AS build +FROM docker.io/gradle:8.6-jdk21-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile index 10f40528c0a..90d51b0b30b 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.4-jdk21-alpine AS build +FROM docker.io/gradle:8.6-jdk21-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile index ce807d1c2fe..93b0e22a963 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.4-jdk21-alpine AS build +FROM docker.io/gradle:8.6-jdk21-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile index d07a610bcd8..ba9b55020b9 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.4-jdk21-alpine AS build +FROM docker.io/gradle:8.6-jdk21-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile index c813f85bf27..a7c28730e03 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.4-jdk21-alpine AS build +FROM docker.io/gradle:8.6-jdk21-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index c28cb74d5d4..abd537c0dd3 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.4-jdk21-alpine AS build +FROM docker.io/gradle:8.6-jdk21-alpine AS build USER root WORKDIR /hexagon diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index 7723b0cae2d..a8eec2e6809 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.4-jdk21-alpine AS build +FROM docker.io/gradle:8.6-jdk21-alpine AS build USER root WORKDIR /hexagon From 6bcabf3f8fc8a6a373d358e5b4f49b4ff7d254fb Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sat, 9 Mar 2024 12:52:08 +0100 Subject: [PATCH 139/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 6 +++--- frameworks/Kotlin/hexagon/gradlew.bat | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 9714488c038..cb67a8d98a9 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,6 +1,6 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "1.9.22" apply false + id "org.jetbrains.kotlin.jvm" version "1.9.23" apply false id "org.graalvm.buildtools.native" version "0.10.1" apply false } @@ -10,12 +10,12 @@ group = "com.hexagonkt" ext { hexagonVersion = "3.5.0" - jettyVersion = "12.0.5" + jettyVersion = "12.0.7" nettyVersion = "4.1.107.Final" hikariVersion = "5.1.0" postgresqlVersion = "42.7.2" - vertxVersion = "4.5.3" + vertxVersion = "4.5.4" cache2kVersion = "2.6.1.Final" applicationClass = "com.hexagonkt.BenchmarkKt" diff --git a/frameworks/Kotlin/hexagon/gradlew.bat b/frameworks/Kotlin/hexagon/gradlew.bat index 93e3f59f135..25da30dbdee 100644 --- a/frameworks/Kotlin/hexagon/gradlew.bat +++ b/frameworks/Kotlin/hexagon/gradlew.bat @@ -43,11 +43,11 @@ 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. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ 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. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail From cc6e87eb3e06298397353f073bc374c913df97a8 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Fri, 15 Mar 2024 17:06:59 +0100 Subject: [PATCH 140/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index cb67a8d98a9..0f7a08ea68f 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -14,8 +14,8 @@ ext { nettyVersion = "4.1.107.Final" hikariVersion = "5.1.0" - postgresqlVersion = "42.7.2" - vertxVersion = "4.5.4" + postgresqlVersion = "42.7.3" + vertxVersion = "4.5.5" cache2kVersion = "2.6.1.Final" applicationClass = "com.hexagonkt.BenchmarkKt" From 1a847a17ce5dd4afc30a034f923eb1a8f60b4361 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sun, 17 Mar 2024 22:27:38 +0100 Subject: [PATCH 141/149] Update Hexagon version --- frameworks/Kotlin/hexagon/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 0f7a08ea68f..9279d3b38fd 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -9,7 +9,7 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.5.0" + hexagonVersion = "3.5.1" jettyVersion = "12.0.7" nettyVersion = "4.1.107.Final" From b05b4333d3aa9e334bee36d43e009916a7b107fb Mon Sep 17 00:00:00 2001 From: jaguililla Date: Sat, 3 Aug 2024 20:51:35 +0200 Subject: [PATCH 142/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 14 +++++++------- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../hexagon/hexagon-helidon-pgclient.dockerfile | 4 ++-- .../Kotlin/hexagon/hexagon-helidon.dockerfile | 4 ++-- .../hexagon/hexagon-jettyloom-pgclient.dockerfile | 4 ++-- .../Kotlin/hexagon/hexagon-jettyloom.dockerfile | 4 ++-- .../hexagon/hexagon-nettyepoll-pgclient.dockerfile | 4 ++-- .../Kotlin/hexagon/hexagon-nettyepoll.dockerfile | 4 ++-- .../Kotlin/hexagon/hexagon-tomcat.dockerfile | 4 ++-- frameworks/Kotlin/hexagon/hexagon.dockerfile | 4 ++-- .../src/main/kotlin/WebListenerServer.kt | 5 +++-- 11 files changed, 27 insertions(+), 26 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 9279d3b38fd..a4d141e5c2a 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,7 +1,7 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "1.9.23" apply false - id "org.graalvm.buildtools.native" version "0.10.1" apply false + id "org.jetbrains.kotlin.jvm" version "2.0.20-RC" apply false + id "org.graalvm.buildtools.native" version "0.10.2" apply false } version = "1.0.0" @@ -9,13 +9,13 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.5.1" - jettyVersion = "12.0.7" - nettyVersion = "4.1.107.Final" + hexagonVersion = "3.6.1" + jettyVersion = "12.0.12" + nettyVersion = "4.1.112.Final" hikariVersion = "5.1.0" postgresqlVersion = "42.7.3" - vertxVersion = "4.5.5" + vertxVersion = "4.5.9" cache2kVersion = "2.6.1.Final" applicationClass = "com.hexagonkt.BenchmarkKt" @@ -30,5 +30,5 @@ subprojects { } tasks.wrapper { - gradleVersion = "8.6" + gradleVersion = "8.9" } diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties index a80b22ce5cf..09523c0e549 100644 --- a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties +++ b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile index d87e78307b0..3b3a1602f55 100644 --- a/frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.6-jdk21-alpine AS build +FROM docker.io/gradle:8.9-jdk21-alpine AS build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN gradle --quiet -x test installDist # # RUNTIME # -FROM docker.io/eclipse-temurin:21-jre-alpine +FROM docker.io/bellsoft/liberica-runtime-container:jre-21-musl ARG PROJECT=hexagon_helidon_pgclient ENV POSTGRESQL_DB_HOST tfb-database diff --git a/frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile b/frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile index 913a9459a06..271fa95dbf8 100644 --- a/frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.6-jdk21-alpine AS build +FROM docker.io/gradle:8.9-jdk21-alpine AS build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN gradle --quiet -x test installDist # # RUNTIME # -FROM docker.io/eclipse-temurin:21-jre-alpine +FROM docker.io/bellsoft/liberica-runtime-container:jre-21-musl ARG PROJECT=hexagon_helidon_postgresql ENV POSTGRESQL_DB_HOST tfb-database diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile index 90d51b0b30b..d6c37bcd77f 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.6-jdk21-alpine AS build +FROM docker.io/gradle:8.9-jdk21-alpine AS build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN gradle --quiet -x test installDist # # RUNTIME # -FROM docker.io/eclipse-temurin:21-jre-alpine +FROM docker.io/bellsoft/liberica-runtime-container:jre-21-musl ARG PROJECT=hexagon_jetty_pgclient ENV POSTGRESQL_DB_HOST tfb-database diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile index 93b0e22a963..07bf482b28e 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.6-jdk21-alpine AS build +FROM docker.io/gradle:8.9-jdk21-alpine AS build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN gradle --quiet -x test installDist # # RUNTIME # -FROM docker.io/eclipse-temurin:21-jre-alpine +FROM docker.io/bellsoft/liberica-runtime-container:jre-21-musl ARG PROJECT=hexagon_jetty_postgresql ENV POSTGRESQL_DB_HOST tfb-database diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile index ba9b55020b9..972347f053b 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.6-jdk21-alpine AS build +FROM docker.io/gradle:8.9-jdk21-alpine AS build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN gradle --quiet -x test installDist # # RUNTIME # -FROM docker.io/eclipse-temurin:21-jre-alpine +FROM docker.io/bellsoft/liberica-runtime-container:jre-21-musl ARG PROJECT=hexagon_nettyepoll_pgclient ENV POSTGRESQL_DB_HOST tfb-database diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile index a7c28730e03..393f73f62a6 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.6-jdk21-alpine AS build +FROM docker.io/gradle:8.9-jdk21-alpine AS build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN gradle --quiet -x test installDist # # RUNTIME # -FROM docker.io/eclipse-temurin:21-jre-alpine +FROM docker.io/bellsoft/liberica-runtime-container:jre-21-musl ARG PROJECT=hexagon_nettyepoll_postgresql ENV POSTGRESQL_DB_HOST tfb-database diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index abd537c0dd3..32e153cbc0a 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.6-jdk21-alpine AS build +FROM docker.io/gradle:8.9-jdk21-alpine AS build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN gradle --quiet -x test war # # RUNTIME # -FROM docker.io/tomcat:10-jre21-temurin-jammy +FROM docker.io/tomcat:11.0.0-jre21-temurin-noble ARG MODULE=/hexagon/hexagon_tomcat_postgresql ENV POSTGRESQL_DB_HOST tfb-database diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index a8eec2e6809..59f89e5cb5c 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/gradle:8.6-jdk21-alpine AS build +FROM docker.io/gradle:8.9-jdk21-alpine AS build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN gradle --quiet -x test installDist # # RUNTIME # -FROM docker.io/eclipse-temurin:21-jre-alpine +FROM docker.io/bellsoft/liberica-runtime-container:jre-21-musl ARG PROJECT=hexagon_jetty_postgresql ENV POSTGRESQL_DB_HOST tfb-database diff --git a/frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/src/main/kotlin/WebListenerServer.kt b/frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/src/main/kotlin/WebListenerServer.kt index 69fe6d13ba6..c7d7ea4449c 100644 --- a/frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/src/main/kotlin/WebListenerServer.kt +++ b/frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/src/main/kotlin/WebListenerServer.kt @@ -6,6 +6,7 @@ import com.hexagonkt.http.model.Header import com.hexagonkt.http.model.Headers import com.hexagonkt.http.handlers.HttpHandler import com.hexagonkt.http.handlers.OnHandler +import com.hexagonkt.http.handlers.PathHandler import com.hexagonkt.http.server.servlet.ServletServer import com.hexagonkt.store.BenchmarkSqlStore import com.hexagonkt.templates.jte.JteAdapter @@ -18,7 +19,7 @@ import jakarta.servlet.annotation.WebListener private companion object { val headers = Headers(Header("server", "Tomcat")) - fun createHandlers(settings: Settings): List { + fun createHandlers(settings: Settings): HttpHandler { val store = BenchmarkSqlStore("postgresql") val templateEngine = JteAdapter(TEXT_HTML, precompiled = true) val templateUrl = urlOf("classpath:fortunes.jte") @@ -28,7 +29,7 @@ import jakarta.servlet.annotation.WebListener send(headers = headers) } - return listOf(serverHeaderHandler, controllerPath) + return PathHandler(serverHeaderHandler, controllerPath) } } } From 3846a22bae0db2769b9db22d23f1498ca0ad2ddb Mon Sep 17 00:00:00 2001 From: jaguililla Date: Thu, 15 Aug 2024 23:22:33 +0200 Subject: [PATCH 143/149] Update dependencies and change settings --- frameworks/Kotlin/hexagon/build.gradle | 6 +++--- .../hexagon/gradle/wrapper/gradle-wrapper.jar | Bin 43462 -> 43504 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- frameworks/Kotlin/hexagon/gradlew | 7 +++++-- frameworks/Kotlin/hexagon/gradlew.bat | 2 ++ .../hexagon/hexagon-helidon-native.dockerfile | 2 ++ .../hexagon-helidon-pgclient.dockerfile | 9 +++++---- .../Kotlin/hexagon/hexagon-helidon.dockerfile | 9 +++++---- .../hexagon/hexagon-jetty-native.dockerfile | 2 ++ .../hexagon-jettyloom-pgclient.dockerfile | 7 ++++--- .../hexagon/hexagon-jettyloom.dockerfile | 7 ++++--- .../hexagon-nettyepoll-pgclient.dockerfile | 7 ++++--- .../hexagon/hexagon-nettyepoll.dockerfile | 7 ++++--- .../Kotlin/hexagon/hexagon-tomcat.dockerfile | 7 ++++--- frameworks/Kotlin/hexagon/hexagon.dockerfile | 7 ++++--- .../src/main/kotlin/BenchmarkPgClientStore.kt | 12 +++++++++--- 16 files changed, 58 insertions(+), 35 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index a4d141e5c2a..5f11a1c40a2 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,6 +1,6 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "2.0.20-RC" apply false + id "org.jetbrains.kotlin.jvm" version "2.0.10" apply false id "org.graalvm.buildtools.native" version "0.10.2" apply false } @@ -9,7 +9,7 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.6.1" + hexagonVersion = "3.6.2" jettyVersion = "12.0.12" nettyVersion = "4.1.112.Final" @@ -30,5 +30,5 @@ subprojects { } tasks.wrapper { - gradleVersion = "8.9" + gradleVersion = "8.10" } diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar index d64cd4917707c1f8861d8cb53dd15194d4248596..2c3521197d7c4586c843d1d3e9090525f1898cde 100644 GIT binary patch delta 34463 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 SXRcJ{65?fGI57uQ5&!`B?F@7P delta 34554 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 diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties index 09523c0e549..9355b415575 100644 --- a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties +++ b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/frameworks/Kotlin/hexagon/gradlew b/frameworks/Kotlin/hexagon/gradlew index 1aa94a42690..f5feea6d6b1 100755 --- a/frameworks/Kotlin/hexagon/gradlew +++ b/frameworks/Kotlin/hexagon/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # 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 +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/frameworks/Kotlin/hexagon/gradlew.bat b/frameworks/Kotlin/hexagon/gradlew.bat index 25da30dbdee..9d21a21834d 100644 --- a/frameworks/Kotlin/hexagon/gradlew.bat +++ b/frameworks/Kotlin/hexagon/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/frameworks/Kotlin/hexagon/hexagon-helidon-native.dockerfile b/frameworks/Kotlin/hexagon/hexagon-helidon-native.dockerfile index c402f0ee792..25a78904f79 100644 --- a/frameworks/Kotlin/hexagon/hexagon-helidon-native.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-helidon-native.dockerfile @@ -16,6 +16,8 @@ RUN ./gradlew --quiet -x test hexagon_helidon_pgclient:nativeCompile FROM scratch ARG PROJECT=hexagon_helidon_pgclient +ENV maximumPoolSize 300 + COPY --from=build /hexagon/$PROJECT/build/native/nativeCompile/$PROJECT / ENTRYPOINT [ "/hexagon_helidon_pgclient" ] diff --git a/frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile index 3b3a1602f55..f11c4e7b2bd 100644 --- a/frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile @@ -1,22 +1,23 @@ # # BUILD # -FROM docker.io/gradle:8.9-jdk21-alpine AS build +FROM docker.io/bellsoft/liberica-runtime-container:jdk-all-22-cds-musl AS build USER root WORKDIR /hexagon ADD . . -RUN gradle --quiet classes -RUN gradle --quiet -x test installDist +RUN ./gradlew --quiet classes +RUN ./gradlew --quiet -x test installDist # # RUNTIME # -FROM docker.io/bellsoft/liberica-runtime-container:jre-21-musl +FROM docker.io/bellsoft/liberica-runtime-container:jre-22-musl ARG PROJECT=hexagon_helidon_pgclient ENV POSTGRESQL_DB_HOST tfb-database ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA +ENV maximumPoolSize 300 COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT diff --git a/frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile b/frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile index 271fa95dbf8..27177de5eb9 100644 --- a/frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile @@ -1,22 +1,23 @@ # # BUILD # -FROM docker.io/gradle:8.9-jdk21-alpine AS build +FROM docker.io/bellsoft/liberica-runtime-container:jdk-all-22-cds-musl AS build USER root WORKDIR /hexagon ADD . . -RUN gradle --quiet classes -RUN gradle --quiet -x test installDist +RUN ./gradlew --quiet classes +RUN ./gradlew --quiet -x test installDist # # RUNTIME # -FROM docker.io/bellsoft/liberica-runtime-container:jre-21-musl +FROM docker.io/bellsoft/liberica-runtime-container:jre-22-musl ARG PROJECT=hexagon_helidon_postgresql ENV POSTGRESQL_DB_HOST tfb-database ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA +ENV maximumPoolSize 300 COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT diff --git a/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile index 2919fdba8b7..b8efc965eb3 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jetty-native.dockerfile @@ -16,6 +16,8 @@ RUN ./gradlew --quiet -x test hexagon_jetty_postgresql:nativeCompile FROM scratch ARG PROJECT=hexagon_jetty_postgresql +ENV maximumPoolSize 300 + COPY --from=build /hexagon/$PROJECT/build/native/nativeCompile/$PROJECT / ENTRYPOINT [ "/hexagon_jetty_postgresql" ] diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile index d6c37bcd77f..21ef3b64c8b 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile @@ -1,13 +1,13 @@ # # BUILD # -FROM docker.io/gradle:8.9-jdk21-alpine AS build +FROM docker.io/bellsoft/liberica-runtime-container:jdk-all-21-cds-musl AS build USER root WORKDIR /hexagon ADD . . -RUN gradle --quiet classes -RUN gradle --quiet -x test installDist +RUN ./gradlew --quiet classes +RUN ./gradlew --quiet -x test installDist # # RUNTIME @@ -17,6 +17,7 @@ ARG PROJECT=hexagon_jetty_pgclient ENV POSTGRESQL_DB_HOST tfb-database ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA -DvirtualThreads=true +ENV maximumPoolSize 300 COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT diff --git a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile index 07bf482b28e..c51c03bc6db 100644 --- a/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile @@ -1,13 +1,13 @@ # # BUILD # -FROM docker.io/gradle:8.9-jdk21-alpine AS build +FROM docker.io/bellsoft/liberica-runtime-container:jdk-all-21-cds-musl AS build USER root WORKDIR /hexagon ADD . . -RUN gradle --quiet classes -RUN gradle --quiet -x test installDist +RUN ./gradlew --quiet classes +RUN ./gradlew --quiet -x test installDist # # RUNTIME @@ -17,6 +17,7 @@ ARG PROJECT=hexagon_jetty_postgresql ENV POSTGRESQL_DB_HOST tfb-database ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA -DvirtualThreads=true +ENV maximumPoolSize 300 COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile index 972347f053b..90c5a0d03c8 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile @@ -1,13 +1,13 @@ # # BUILD # -FROM docker.io/gradle:8.9-jdk21-alpine AS build +FROM docker.io/bellsoft/liberica-runtime-container:jdk-all-21-cds-musl AS build USER root WORKDIR /hexagon ADD . . -RUN gradle --quiet classes -RUN gradle --quiet -x test installDist +RUN ./gradlew --quiet classes +RUN ./gradlew --quiet -x test installDist # # RUNTIME @@ -17,6 +17,7 @@ ARG PROJECT=hexagon_nettyepoll_pgclient ENV POSTGRESQL_DB_HOST tfb-database ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA +ENV maximumPoolSize 300 COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT diff --git a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile index 393f73f62a6..35a0e4729b7 100644 --- a/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile @@ -1,13 +1,13 @@ # # BUILD # -FROM docker.io/gradle:8.9-jdk21-alpine AS build +FROM docker.io/bellsoft/liberica-runtime-container:jdk-all-21-cds-musl AS build USER root WORKDIR /hexagon ADD . . -RUN gradle --quiet classes -RUN gradle --quiet -x test installDist +RUN ./gradlew --quiet classes +RUN ./gradlew --quiet -x test installDist # # RUNTIME @@ -17,6 +17,7 @@ ARG PROJECT=hexagon_nettyepoll_postgresql ENV POSTGRESQL_DB_HOST tfb-database ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA +ENV maximumPoolSize 300 COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index 32e153cbc0a..42f28071128 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -1,13 +1,13 @@ # # BUILD # -FROM docker.io/gradle:8.9-jdk21-alpine AS build +FROM docker.io/bellsoft/liberica-runtime-container:jdk-all-21-cds-musl AS build USER root WORKDIR /hexagon ADD . . -RUN gradle --quiet classes -RUN gradle --quiet -x test war +RUN ./gradlew --quiet classes +RUN ./gradlew --quiet -x test war # # RUNTIME @@ -17,5 +17,6 @@ ARG MODULE=/hexagon/hexagon_tomcat_postgresql ENV POSTGRESQL_DB_HOST tfb-database ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA +ENV maximumPoolSize 300 COPY --from=build $MODULE/build/libs/ROOT.war /usr/local/tomcat/webapps/ROOT.war diff --git a/frameworks/Kotlin/hexagon/hexagon.dockerfile b/frameworks/Kotlin/hexagon/hexagon.dockerfile index 59f89e5cb5c..2654c706db1 100644 --- a/frameworks/Kotlin/hexagon/hexagon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon.dockerfile @@ -1,13 +1,13 @@ # # BUILD # -FROM docker.io/gradle:8.9-jdk21-alpine AS build +FROM docker.io/bellsoft/liberica-runtime-container:jdk-all-21-cds-musl AS build USER root WORKDIR /hexagon ADD . . -RUN gradle --quiet classes -RUN gradle --quiet -x test installDist +RUN ./gradlew --quiet classes +RUN ./gradlew --quiet -x test installDist # # RUNTIME @@ -17,6 +17,7 @@ ARG PROJECT=hexagon_jetty_postgresql ENV POSTGRESQL_DB_HOST tfb-database ENV JDK_JAVA_OPTIONS -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA +ENV maximumPoolSize 300 COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT diff --git a/frameworks/Kotlin/hexagon/store_pgclient/src/main/kotlin/BenchmarkPgClientStore.kt b/frameworks/Kotlin/hexagon/store_pgclient/src/main/kotlin/BenchmarkPgClientStore.kt index 1fb9547353f..510abda0295 100644 --- a/frameworks/Kotlin/hexagon/store_pgclient/src/main/kotlin/BenchmarkPgClientStore.kt +++ b/frameworks/Kotlin/hexagon/store_pgclient/src/main/kotlin/BenchmarkPgClientStore.kt @@ -6,8 +6,10 @@ import com.hexagonkt.model.CachedWorld import com.hexagonkt.model.Fortune import com.hexagonkt.model.World import io.vertx.core.Future +import io.vertx.core.Vertx +import io.vertx.core.VertxOptions +import io.vertx.pgclient.PgBuilder import io.vertx.pgclient.PgConnectOptions -import io.vertx.pgclient.PgPool import io.vertx.sqlclient.* import org.cache2k.Cache @@ -35,11 +37,15 @@ class BenchmarkPgClientStore( private val poolOptions: PoolOptions by lazy { PoolOptions().apply { val environment = Jvm.systemSettingOrNull("BENCHMARK_ENV")?.lowercase() - maxSize = 8 + if (environment == "citrine") Jvm.cpuCount else Jvm.cpuCount * 2 + val poolSize = 8 + if (environment == "citrine") Jvm.cpuCount else Jvm.cpuCount * 2 + maxSize = Jvm.systemSettingOrNull(Int::class, "maximumPoolSize") ?: poolSize } } - private val dataSource: SqlClient by lazy { PgPool.client(connectOptions, poolOptions) } + private val dataSource: SqlClient by lazy { + val vertx = Vertx.vertx(VertxOptions().setPreferNativeTransport(true)) + PgBuilder.client().using(vertx).connectingTo(connectOptions).with(poolOptions).build() + } override fun findAllFortunes(): List = dataSource.preparedQuery(SELECT_ALL_FORTUNES) From 30c9830883dd35f8bad05d626638a4a81a2b80c9 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 18 Sep 2024 22:32:02 +0200 Subject: [PATCH 144/149] Update dependencies and change settings --- frameworks/Kotlin/hexagon/build.gradle | 14 +++++++------- .../src/main/kotlin/Benchmark.kt | 18 +++++++++++++++--- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index 5f11a1c40a2..d1f77b2b178 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,7 +1,7 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "2.0.10" apply false - id "org.graalvm.buildtools.native" version "0.10.2" apply false + id "org.jetbrains.kotlin.jvm" version "2.0.20" apply false + id "org.graalvm.buildtools.native" version "0.10.3" apply false } version = "1.0.0" @@ -9,13 +9,13 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.6.2" - jettyVersion = "12.0.12" - nettyVersion = "4.1.112.Final" + hexagonVersion = "3.7.0" + jettyVersion = "12.0.13" + nettyVersion = "4.1.113.Final" hikariVersion = "5.1.0" - postgresqlVersion = "42.7.3" - vertxVersion = "4.5.9" + postgresqlVersion = "42.7.4" + vertxVersion = "4.5.10" cache2kVersion = "2.6.1.Final" applicationClass = "com.hexagonkt.BenchmarkKt" diff --git a/frameworks/Kotlin/hexagon/hexagon_helidon_pgclient/src/main/kotlin/Benchmark.kt b/frameworks/Kotlin/hexagon/hexagon_helidon_pgclient/src/main/kotlin/Benchmark.kt index d38d33281f8..a5778a2c353 100644 --- a/frameworks/Kotlin/hexagon/hexagon_helidon_pgclient/src/main/kotlin/Benchmark.kt +++ b/frameworks/Kotlin/hexagon/hexagon_helidon_pgclient/src/main/kotlin/Benchmark.kt @@ -1,18 +1,30 @@ package com.hexagonkt +import com.hexagonkt.core.Jvm.systemSettingOrNull import com.hexagonkt.core.media.TEXT_HTML import com.hexagonkt.core.urlOf import com.hexagonkt.http.server.helidon.HelidonServerAdapter import com.hexagonkt.store.BenchmarkPgClientStore import com.hexagonkt.templates.jte.JteAdapter +import java.time.Duration fun main() { - val settings = Settings() val store = BenchmarkPgClientStore("postgresql") val templateEngine = JteAdapter(TEXT_HTML, precompiled = true) val templateUrl = urlOf("classpath:fortunes.jte") - val engine = HelidonServerAdapter() + val engine = HelidonServerAdapter( + backlog = systemSettingOrNull("backlog") ?: (8 * 1024), + writeQueueLength = systemSettingOrNull("writeQueueLength") ?: (8 * 1024), + readTimeout = Duration.parse(systemSettingOrNull("readTimeout") ?: "PT0S"), + connectTimeout = Duration.parse(systemSettingOrNull("connectTimeout") ?: "PT0S"), + tcpNoDelay = systemSettingOrNull("tcpNoDelay") ?: true, + receiveLog = systemSettingOrNull("receiveLog") ?: false, + sendLog = systemSettingOrNull("sendLog") ?: false, + validatePath = systemSettingOrNull("validatePath") ?: false, + validateRequestHeaders = systemSettingOrNull("validateRequestHeaders") ?: false, + validateResponseHeaders = systemSettingOrNull("validateResponseHeaders") ?: false, + ) - val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings) + val benchmark = Benchmark(engine, store, templateEngine, templateUrl, Settings()) benchmark.server.start() } From 97f4f7d215ee0d48a4da4527287d87d432c34893 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Wed, 30 Oct 2024 09:27:02 +0100 Subject: [PATCH 145/149] Update dependencies --- frameworks/Kotlin/hexagon/build.gradle | 12 ++++++------ .../hexagon/gradle/wrapper/gradle-wrapper.jar | Bin 43504 -> 43583 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index d1f77b2b178..c33d231f630 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,6 +1,6 @@ plugins { - id "org.jetbrains.kotlin.jvm" version "2.0.20" apply false + id "org.jetbrains.kotlin.jvm" version "2.0.21" apply false id "org.graalvm.buildtools.native" version "0.10.3" apply false } @@ -9,11 +9,11 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.7.0" - jettyVersion = "12.0.13" - nettyVersion = "4.1.113.Final" + hexagonVersion = "3.7.2" + jettyVersion = "12.0.14" + nettyVersion = "4.1.114.Final" - hikariVersion = "5.1.0" + hikariVersion = "6.0.0" postgresqlVersion = "42.7.4" vertxVersion = "4.5.10" cache2kVersion = "2.6.1.Final" @@ -30,5 +30,5 @@ subprojects { } tasks.wrapper { - gradleVersion = "8.10" + gradleVersion = "8.10.2" } diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.jar index 2c3521197d7c4586c843d1d3e9090525f1898cde..a4b76b9530d66f5e68d973ea569d8e19de379189 100644 GIT binary patch delta 3990 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 diff --git a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties index 9355b415575..df97d72b8b9 100644 --- a/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties +++ b/frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From efa1fb8ad0f918241bb64b2d5e6adeab857411b9 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Tue, 24 Dec 2024 09:37:05 +0100 Subject: [PATCH 146/149] Update dependencies and batch sql --- frameworks/Kotlin/hexagon/build.gradle | 12 ++++++------ .../hexagon/hexagon-helidon-pgclient.dockerfile | 4 ++-- frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile | 4 ++-- frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile | 2 +- .../store_sql/src/main/kotlin/BenchmarkSqlStore.kt | 6 +++++- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/frameworks/Kotlin/hexagon/build.gradle b/frameworks/Kotlin/hexagon/build.gradle index c33d231f630..f739a6f3418 100644 --- a/frameworks/Kotlin/hexagon/build.gradle +++ b/frameworks/Kotlin/hexagon/build.gradle @@ -1,7 +1,7 @@ plugins { id "org.jetbrains.kotlin.jvm" version "2.0.21" apply false - id "org.graalvm.buildtools.native" version "0.10.3" apply false + id "org.graalvm.buildtools.native" version "0.10.4" apply false } version = "1.0.0" @@ -9,13 +9,13 @@ description = "TFB benchmark" group = "com.hexagonkt" ext { - hexagonVersion = "3.7.2" - jettyVersion = "12.0.14" - nettyVersion = "4.1.114.Final" + hexagonVersion = "3.7.3" + jettyVersion = "12.0.16" + nettyVersion = "4.1.116.Final" - hikariVersion = "6.0.0" + hikariVersion = "6.2.1" postgresqlVersion = "42.7.4" - vertxVersion = "4.5.10" + vertxVersion = "4.5.11" cache2kVersion = "2.6.1.Final" applicationClass = "com.hexagonkt.BenchmarkKt" diff --git a/frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile b/frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile index f11c4e7b2bd..2ad89ca5713 100644 --- a/frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-helidon-pgclient.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/bellsoft/liberica-runtime-container:jdk-all-22-cds-musl AS build +FROM docker.io/bellsoft/liberica-runtime-container:jdk-all-23-cds-musl AS build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN ./gradlew --quiet -x test installDist # # RUNTIME # -FROM docker.io/bellsoft/liberica-runtime-container:jre-22-musl +FROM docker.io/bellsoft/liberica-runtime-container:jre-23-musl ARG PROJECT=hexagon_helidon_pgclient ENV POSTGRESQL_DB_HOST tfb-database diff --git a/frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile b/frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile index 27177de5eb9..632cc8720b5 100644 --- a/frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-helidon.dockerfile @@ -1,7 +1,7 @@ # # BUILD # -FROM docker.io/bellsoft/liberica-runtime-container:jdk-all-22-cds-musl AS build +FROM docker.io/bellsoft/liberica-runtime-container:jdk-all-23-cds-musl AS build USER root WORKDIR /hexagon @@ -12,7 +12,7 @@ RUN ./gradlew --quiet -x test installDist # # RUNTIME # -FROM docker.io/bellsoft/liberica-runtime-container:jre-22-musl +FROM docker.io/bellsoft/liberica-runtime-container:jre-23-musl ARG PROJECT=hexagon_helidon_postgresql ENV POSTGRESQL_DB_HOST tfb-database diff --git a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile index 42f28071128..dfc6c521a1d 100644 --- a/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile +++ b/frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile @@ -12,7 +12,7 @@ RUN ./gradlew --quiet -x test war # # RUNTIME # -FROM docker.io/tomcat:11.0.0-jre21-temurin-noble +FROM docker.io/tomcat:11-jre21-temurin-noble ARG MODULE=/hexagon/hexagon_tomcat_postgresql ENV POSTGRESQL_DB_HOST tfb-database diff --git a/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt b/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt index 501a4d9ce34..0d854baec40 100644 --- a/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt +++ b/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt @@ -62,6 +62,7 @@ class BenchmarkSqlStore( override fun replaceWorlds(worlds: List) { dataSource.connection.use { con: Connection -> + con.autoCommit = false val stmtSelect = con.prepareStatement(SELECT_WORLD) val stmtUpdate = con.prepareStatement(UPDATE_WORLD) @@ -76,8 +77,11 @@ class BenchmarkSqlStore( stmtUpdate.setInt(1, newRandomNumber) stmtUpdate.setInt(2, worldId) - stmtUpdate.executeUpdate() +// stmtUpdate.executeUpdate() + stmtUpdate.addBatch() } + stmtUpdate.executeBatch() + con.commit() } } From 34125b7402f94d442dce5d8120321721f29ac761 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Tue, 31 Dec 2024 13:27:14 +0100 Subject: [PATCH 147/149] Improve SQL --- .../src/main/kotlin/BenchmarkPgClientStore.kt | 8 ++++---- .../store_sql/src/main/kotlin/BenchmarkSqlStore.kt | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/frameworks/Kotlin/hexagon/store_pgclient/src/main/kotlin/BenchmarkPgClientStore.kt b/frameworks/Kotlin/hexagon/store_pgclient/src/main/kotlin/BenchmarkPgClientStore.kt index 510abda0295..2b09d73f6f5 100644 --- a/frameworks/Kotlin/hexagon/store_pgclient/src/main/kotlin/BenchmarkPgClientStore.kt +++ b/frameworks/Kotlin/hexagon/store_pgclient/src/main/kotlin/BenchmarkPgClientStore.kt @@ -19,9 +19,10 @@ class BenchmarkPgClientStore( ) : BenchmarkStore(settings) { companion object { - private const val SELECT_WORLD: String = "select * from world where id = $1" + private const val LOAD_WORLDS: String = "select id, randomNumber from world" + private const val SELECT_WORLD: String = "select id, randomNumber 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 const val SELECT_ALL_FORTUNES: String = "select id, message from fortune" } private val connectOptions: PgConnectOptions by lazy { @@ -81,13 +82,12 @@ class BenchmarkPgClientStore( .toCompletionStage() .toCompletableFuture() .get() - } } override fun initWorldsCache(cache: Cache) { dataSource - .preparedQuery("select * from world") + .preparedQuery(LOAD_WORLDS) .execute() .map { rowSet -> rowSet.map { row -> diff --git a/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt b/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt index 0d854baec40..895f550fb7a 100644 --- a/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt +++ b/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt @@ -16,9 +16,10 @@ class BenchmarkSqlStore( ) : BenchmarkStore(settings) { companion object { - private const val SELECT_WORLD: String = "select * from world where id = ?" + private const val LOAD_WORLDS: String = "select id, randomNumber from world" + private const val SELECT_WORLD: String = "select id, randomNumber 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 const val SELECT_ALL_FORTUNES: String = "select id, message from fortune" } private val dataSource: HikariDataSource by lazy { @@ -87,7 +88,7 @@ class BenchmarkSqlStore( override fun initWorldsCache(cache: Cache) { dataSource.connection.use { con: Connection -> - val stmtSelect = con.prepareStatement("select * from world") + val stmtSelect = con.prepareStatement(LOAD_WORLDS) val rs = stmtSelect.executeQuery() while (rs.next()) { From 215a4d48451b58e9dc7df94ee98d360d6db8542e Mon Sep 17 00:00:00 2001 From: jaguililla Date: Tue, 31 Dec 2024 15:27:37 +0100 Subject: [PATCH 148/149] Improve SQL --- .../src/main/kotlin/BenchmarkSqlStore.kt | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt b/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt index 895f550fb7a..a133e407874 100644 --- a/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt +++ b/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt @@ -63,26 +63,22 @@ class BenchmarkSqlStore( override fun replaceWorlds(worlds: List) { dataSource.connection.use { con: Connection -> - con.autoCommit = false val stmtSelect = con.prepareStatement(SELECT_WORLD) - val stmtUpdate = con.prepareStatement(UPDATE_WORLD) - worlds.forEach { - val worldId = it.id - val newRandomNumber = it.randomNumber - - stmtSelect.setInt(1, worldId) + stmtSelect.setInt(1, it.id) val rs = stmtSelect.executeQuery() rs.next() rs.getInt(2) // Read 'randomNumber' to comply with Test type 5, point 6 + } - stmtUpdate.setInt(1, newRandomNumber) - stmtUpdate.setInt(2, worldId) -// stmtUpdate.executeUpdate() - stmtUpdate.addBatch() + val stmtUpdate = con.prepareStatement(UPDATE_WORLD) + worlds.forEach { + stmtUpdate.setInt(1, it.randomNumber) + stmtUpdate.setInt(2, it.id) + stmtUpdate.executeUpdate() +// stmtUpdate.addBatch() } - stmtUpdate.executeBatch() - con.commit() +// stmtUpdate.executeBatch() } } From 936f941d3d332580817d19030c76aeb3827c4d23 Mon Sep 17 00:00:00 2001 From: jaguililla Date: Tue, 31 Dec 2024 17:25:53 +0100 Subject: [PATCH 149/149] Improve SQL --- .../hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt b/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt index a133e407874..14558b1a2bd 100644 --- a/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt +++ b/frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt @@ -76,9 +76,7 @@ class BenchmarkSqlStore( stmtUpdate.setInt(1, it.randomNumber) stmtUpdate.setInt(2, it.id) stmtUpdate.executeUpdate() -// stmtUpdate.addBatch() } -// stmtUpdate.executeBatch() } }