浏览代码

Merge pull request #27 from TechEmpower/master

aa
三刀 2 年之前
父节点
当前提交
7dc16b27f2
共有 100 个文件被更改,包括 1060 次插入698 次删除
  1. 16 16
      Dockerfile
  2. 4 3
      frameworks/C/h2o/README.md
  3. 5 5
      frameworks/C/h2o/h2o.dockerfile
  4. 5 2
      frameworks/C/h2o/h2o.sh
  5. 6 6
      frameworks/C/h2o/src/database.c
  6. 1 1
      frameworks/C/h2o/src/handlers/fortune.c
  7. 2 2
      frameworks/C/h2o/src/main.c
  8. 25 1
      frameworks/Go/aah/src/benchmark/go.mod
  9. 31 4
      frameworks/Go/aah/src/benchmark/go.sum
  10. 3 1
      frameworks/Go/fiber/fiber-prefork.dockerfile
  11. 1 1
      frameworks/Go/fiber/fiber.dockerfile
  12. 15 13
      frameworks/Go/fiber/src/go.mod
  13. 38 166
      frameworks/Go/fiber/src/go.sum
  14. 8 4
      frameworks/Go/fiber/src/server.go
  15. 6 0
      frameworks/Go/fiber/src/server_test.go
  16. 1 1
      frameworks/Java/micronaut/gradle.properties
  17. 0 21
      frameworks/Java/redkale/benchmark_config.json
  18. 0 3
      frameworks/Java/redkale/conf/application.xml
  19. 0 8
      frameworks/Java/redkale/conf/source-mysql.properties
  20. 0 15
      frameworks/Java/redkale/config.toml
  21. 0 12
      frameworks/Java/redkale/redkale-mysql.dockerfile
  22. 29 5
      frameworks/Java/redkale/src/main/java/org/redkalex/benchmark/BenchmarkService.java
  23. 0 85
      frameworks/Java/redkale/src/main/java/org/redkalex/benchmark/CachedWorld.java
  24. 4 7
      frameworks/Java/redkale/src/main/java/org/redkalex/benchmark/World.java
  25. 2 2
      frameworks/Java/spring-webflux/spring-webflux-jdbc.dockerfile
  26. 2 2
      frameworks/Java/spring-webflux/spring-webflux-mongo.dockerfile
  27. 2 2
      frameworks/Java/spring-webflux/spring-webflux-pgclient.dockerfile
  28. 2 2
      frameworks/Java/spring-webflux/spring-webflux-rxjdbc.dockerfile
  29. 2 2
      frameworks/Java/spring-webflux/spring-webflux.dockerfile
  30. 10 45
      frameworks/Kotlin/hexagon/build.gradle
  31. 34 0
      frameworks/Kotlin/hexagon/core/build.gradle
  32. 27 0
      frameworks/Kotlin/hexagon/core/src/main/kotlin/Benchmark.kt
  33. 12 13
      frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt
  34. 4 3
      frameworks/Kotlin/hexagon/core/src/main/kotlin/Settings.kt
  35. 0 0
      frameworks/Kotlin/hexagon/core/src/main/kotlin/model/CachedWorld.kt
  36. 0 0
      frameworks/Kotlin/hexagon/core/src/main/kotlin/model/Fortune.kt
  37. 0 0
      frameworks/Kotlin/hexagon/core/src/main/kotlin/model/Message.kt
  38. 0 0
      frameworks/Kotlin/hexagon/core/src/main/kotlin/model/World.kt
  39. 0 0
      frameworks/Kotlin/hexagon/core/src/main/kotlin/store/BenchmarkStore.kt
  40. 0 0
      frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.pebble.html
  41. 24 0
      frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.rocker.html
  42. 5 8
      frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile
  43. 5 8
      frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile
  44. 6 9
      frameworks/Kotlin/hexagon/hexagon-netty.dockerfile
  45. 6 9
      frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile
  46. 6 9
      frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile
  47. 5 6
      frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile
  48. 6 9
      frameworks/Kotlin/hexagon/hexagon.dockerfile
  49. 13 0
      frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/build.gradle
  50. 23 0
      frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/src/main/kotlin/Benchmark.kt
  51. 13 0
      frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/build.gradle
  52. 23 0
      frameworks/Kotlin/hexagon/hexagon_jetty_postgresql/src/main/kotlin/Benchmark.kt
  53. 13 0
      frameworks/Kotlin/hexagon/hexagon_netty_postgresql/build.gradle
  54. 17 0
      frameworks/Kotlin/hexagon/hexagon_netty_postgresql/src/main/kotlin/Benchmark.kt
  55. 14 0
      frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/build.gradle
  56. 17 0
      frameworks/Kotlin/hexagon/hexagon_nettyepoll_pgclient/src/main/kotlin/Benchmark.kt
  57. 14 0
      frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/build.gradle
  58. 17 0
      frameworks/Kotlin/hexagon/hexagon_nettyepoll_postgresql/src/main/kotlin/Benchmark.kt
  59. 15 0
      frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/build.gradle
  60. 9 3
      frameworks/Kotlin/hexagon/hexagon_tomcat_postgresql/src/main/kotlin/WebListenerServer.kt
  61. 13 0
      frameworks/Kotlin/hexagon/settings.gradle
  62. 0 56
      frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt
  63. 6 0
      frameworks/Kotlin/hexagon/store_pgclient/build.gradle
  64. 3 2
      frameworks/Kotlin/hexagon/store_pgclient/src/main/kotlin/BenchmarkPgClientStore.kt
  65. 6 0
      frameworks/Kotlin/hexagon/store_sql/build.gradle
  66. 1 1
      frameworks/Kotlin/hexagon/store_sql/src/main/kotlin/BenchmarkSqlStore.kt
  67. 3 3
      frameworks/Kotlin/http4k/build.gradle
  68. 1 1
      frameworks/Kotlin/http4k/gradle/wrapper/gradle-wrapper.properties
  69. 2 2
      frameworks/Kotlin/http4k/http4k-apache-graalvm.dockerfile
  70. 1 1
      frameworks/Kotlin/http4k/http4k-apache.dockerfile
  71. 1 1
      frameworks/Kotlin/http4k/http4k-apache4.dockerfile
  72. 2 2
      frameworks/Kotlin/http4k/http4k-graalvm.dockerfile
  73. 1 1
      frameworks/Kotlin/http4k/http4k-jetty.dockerfile
  74. 1 1
      frameworks/Kotlin/http4k/http4k-ktorcio.dockerfile
  75. 1 1
      frameworks/Kotlin/http4k/http4k-ktornetty.dockerfile
  76. 1 1
      frameworks/Kotlin/http4k/http4k-netty.dockerfile
  77. 1 1
      frameworks/Kotlin/http4k/http4k-ratpack.dockerfile
  78. 1 1
      frameworks/Kotlin/http4k/http4k-undertow.dockerfile
  79. 1 1
      frameworks/Kotlin/http4k/http4k.dockerfile
  80. 6 25
      frameworks/Kotlin/http4k/jettyloom-jdbc/src/main/kotlin/JettyLoom.kt
  81. 5 24
      frameworks/Kotlin/http4k/jettyloom-pgclient/src/main/kotlin/JettyLoom.kt
  82. 23 3
      frameworks/Kotlin/http4k/undertow/src/main/kotlin/Http4kUndertowServer.kt
  83. 2 2
      frameworks/Pascal/mormot/setup_and_build.sh
  84. 7 6
      frameworks/Pascal/mormot/src/raw.lpi
  85. 43 32
      frameworks/Pascal/mormot/src/raw.pas
  86. 1 1
      frameworks/Python/eve/requirements.txt
  87. 6 2
      frameworks/Ruby/h2o_mruby/README.md
  88. 24 13
      frameworks/Ruby/h2o_mruby/h2o_mruby.dockerfile
  89. 19 0
      frameworks/Rust/anansi/Cargo.toml
  90. 36 0
      frameworks/Rust/anansi/README.md
  91. 11 0
      frameworks/Rust/anansi/anansi-raw.dockerfile
  92. 14 0
      frameworks/Rust/anansi/anansi.dockerfile
  93. 52 0
      frameworks/Rust/anansi/benchmark_config.json
  94. 19 0
      frameworks/Rust/anansi/settings.toml
  95. 3 0
      frameworks/Rust/anansi/src/hello/migrations/mod.rs
  96. 7 0
      frameworks/Rust/anansi/src/hello/mod.rs
  97. 47 0
      frameworks/Rust/anansi/src/hello/records.rs
  98. 3 0
      frameworks/Rust/anansi/src/hello/urls.rs
  99. 5 0
      frameworks/Rust/anansi/src/hello/world/mod.rs
  100. 133 0
      frameworks/Rust/anansi/src/hello/world/raw.rs

+ 16 - 16
Dockerfile

@@ -1,26 +1,26 @@
 FROM buildpack-deps:bionic
 
+ARG DEBIAN_FRONTEND=noninteractive
+# WARNING: DON'T PUT A SPACE AFTER ANY BACKSLASH OR APT WILL BREAK
 # One -q produces output suitable for logging (mostly hides
 # progress indicators)
-RUN apt-get -yqq update
+RUN apt-get -yqq update && apt-get -yqq install \
+      -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" \
+      cloc \
+      dstat                       `# Collect resource usage statistics` \
+      git-core \
+      libmysqlclient-dev          `# Needed for MySQL-python` \
+      python-dev \
+      python-pip \
+      siege \
+      software-properties-common
 
-# WARNING: DONT PUT A SPACE AFTER ANY BACKSLASH OR APT WILL BREAK
-RUN apt-get -yqq install -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" \
-  git-core \
-  cloc dstat                    `# Collect resource usage statistics` \
-  python-dev \
-  python-pip \
-  software-properties-common \
-  libmysqlclient-dev            `# Needed for MySQL-python`
-
-RUN pip install colorama==0.3.1 requests MySQL-python psycopg2-binary pymongo docker==4.0.2 psutil
-
-RUN apt-get install -yqq siege
+RUN pip install colorama==0.3.1 docker==4.0.2 MySQL-python psutil psycopg2-binary pymongo requests
 
 # Fix for docker-py trying to import one package from the wrong location
-RUN cp -r /usr/local/lib/python2.7/dist-packages/backports/ssl_match_hostname/ /usr/lib/python2.7/dist-packages/backports
+RUN cp -r /usr/local/lib/python2.7/dist-packages/backports/ssl_match_hostname /usr/lib/python2.7/dist-packages/backports
 
-ENV PYTHONPATH /FrameworkBenchmarks
-ENV FWROOT /FrameworkBenchmarks
+ENV PYTHONPATH=/FrameworkBenchmarks
+ENV FWROOT=/FrameworkBenchmarks
 
 ENTRYPOINT ["python", "/FrameworkBenchmarks/toolset/run-tests.py"]

+ 4 - 3
frameworks/C/h2o/README.md

@@ -17,9 +17,10 @@ The test implementations are located into the `src/handlers` directory - refer t
 ## Performance tuning
 
 If the test environment changes, it will probably be necessary to tune some of the framework
-settings in order to achieve the best performance possible. The most significant parameter is
-the maximum number of database connections per thread, which is controlled by the `DB_CONN`
-variable in the `h2o.sh` script.
+settings in order to achieve the best performance possible. The most significant parameters are the
+maximum number of database connections per thread and the maximum number of pipelined database
+queries per database connection, which are controlled by the `DB_CONN` and the `DB_PIPELINE`
+variables respectively in the `h2o.sh` script.
 
 ## Performance issues
 

+ 5 - 5
frameworks/C/h2o/h2o.dockerfile

@@ -3,9 +3,9 @@ FROM ubuntu:22.04
 WORKDIR /h2o_app_src
 COPY ./ ./
 
-ENV DEBIAN_FRONTEND noninteractive
-RUN apt-get update && \
-    apt-get install -yqq autoconf bison cmake curl file flex g++ git libnuma-dev libpq-dev \
+ARG DEBIAN_FRONTEND=noninteractive
+RUN apt-get -yqq update && \
+    apt-get -yqq install autoconf bison cmake curl file flex g++ git libnuma-dev libpq-dev \
                          libssl-dev libtool libyajl-dev libz-dev make ninja-build wget
 
 ### Install mustache-c
@@ -13,7 +13,7 @@ RUN apt-get update && \
 ARG MUSTACHE_C_REVISION=c1948c599edfe48c6099ed70ab1d5911d8c3ddc8
 
 ARG MUSTACHE_C_BUILD_DIR=mustache-c-build
-ENV MUSTACHE_C_PREFIX /opt/mustache-c
+ENV MUSTACHE_C_PREFIX=/opt/mustache-c
 
 RUN mkdir -p "$MUSTACHE_C_BUILD_DIR" && \
     cd "$MUSTACHE_C_BUILD_DIR" && \
@@ -29,7 +29,7 @@ RUN mkdir -p "$MUSTACHE_C_BUILD_DIR" && \
 ARG H2O_VERSION=v2.2.6
 
 ARG H2O_BUILD_DIR=h2o-build
-ENV H2O_PREFIX /opt/h2o
+ENV H2O_PREFIX=/opt/h2o
 
 RUN mkdir -p "${H2O_BUILD_DIR}/build" && \
     cd "$H2O_BUILD_DIR" && \

+ 5 - 2
frameworks/C/h2o/h2o.sh

@@ -25,9 +25,11 @@ if [[ -z "$MUSTACHE_C_PREFIX" ]]; then
 fi
 
 if [[ "$BENCHMARK_ENV" = "Azure" ]]; then
-	DB_CONN=2
+	DB_CONN=1
+	DB_PIPELINE=64
 else
 	DB_CONN=1
+	DB_PIPELINE=64
 fi
 
 build_h2o_app()
@@ -49,7 +51,7 @@ run_curl()
 run_h2o_app()
 {
 	LD_LIBRARY_PATH="${MUSTACHE_C_PREFIX}/lib:$LD_LIBRARY_PATH" \
-	taskset -c "$1" "$2/h2o_app" -a20 -e32 -f "$3/template" -m "$DB_CONN" "$4" "$5" \
+	taskset -c "$1" "$2/h2o_app" -a20 -e "$DB_PIPELINE" -f "$3/template" -m "$DB_CONN" "$4" "$5" \
 	        -d "host=$DBHOST dbname=hello_world user=benchmarkdbuser sslmode=disable \
 	            password=benchmarkdbpass" &
 }
@@ -81,5 +83,6 @@ popd
 rm -rf "$H2O_APP_BUILD_DIR"
 echo "Running h2o_app in the $BENCHMARK_ENV environment."
 echo "Maximum database connections per thread: $DB_CONN"
+echo "Maximum pipelined database queries per database connection: $DB_PIPELINE"
 run_h2o_app 0 "${H2O_APP_PREFIX}/bin" "${H2O_APP_PREFIX}/share/h2o_app"
 wait

+ 6 - 6
frameworks/C/h2o/src/database.c

@@ -186,12 +186,14 @@ static void error_notification(db_conn_pool_t *pool, bool timeout, const char *e
 
 static void on_database_connect_error(db_conn_t *conn, bool timeout, const char *error_string)
 {
-	error_notification(conn->pool, timeout, error_string);
+	db_conn_pool_t * const pool = conn->pool;
+
 	h2o_timeout_unlink(&conn->timeout);
 	h2o_socket_read_stop(conn->sock);
 	h2o_socket_close(conn->sock);
 	PQfinish(conn->conn);
 	free(conn);
+	error_notification(pool, timeout, error_string);
 }
 
 static void on_database_connect_read_ready(h2o_socket_t *sock, const char *err)
@@ -409,12 +411,10 @@ static void on_database_write_ready(h2o_socket_t *sock, const char *err)
 			LIBRARY_ERROR("PQflush", PQerrorMessage(conn->conn));
 			on_database_error(conn, DB_ERROR);
 		}
-		else {
-			if (send_status)
-				h2o_socket_notify_write(conn->sock, on_database_write_ready);
-
+		else if (send_status)
+			h2o_socket_notify_write(conn->sock, on_database_write_ready);
+		else
 			process_queries(conn);
-		}
 	}
 }
 

+ 1 - 1
frameworks/C/h2o/src/handlers/fortune.c

@@ -41,7 +41,7 @@
 #define FORTUNE_TABLE_NAME "Fortune"
 #define FORTUNE_QUERY "SELECT * FROM " FORTUNE_TABLE_NAME ";"
 #define ID_FIELD_NAME "id"
-#define MAX_IOVEC 64
+#define MAX_IOVEC 128
 #define MESSAGE_FIELD_NAME "message"
 #define NEW_FORTUNE_ID "0"
 #define NEW_FORTUNE_MESSAGE "Additional fortune added at request time."

+ 2 - 2
frameworks/C/h2o/src/main.c

@@ -46,7 +46,7 @@
 	"[-b <bind address>] " \
 	"[-c <certificate file>] " \
 	"[-d <database connection string>] " \
-	"[-e <max pipelined database queries>] " \
+	"[-e <max pipelined database queries per database connection>] " \
 	"[-f <template file path>] " \
 	"[-j <max reused JSON generators>] " \
 	"[-k <private key file>] " \
@@ -264,7 +264,7 @@ static void set_default_options(config_t *config)
 		config->max_accept = 10;
 
 	if (!config->max_db_conn_num)
-		config->max_db_conn_num = 10;
+		config->max_db_conn_num = 1;
 
 	if (!config->max_pipeline_query_num)
 		config->max_pipeline_query_num = 16;

+ 25 - 1
frameworks/Go/aah/src/benchmark/go.mod

@@ -1,8 +1,32 @@
 module benchmark
 
 require (
-	aahframe.work v0.12.2
+	aahframe.work v0.12.4
 	github.com/go-sql-driver/mysql v1.4.1
 	github.com/jackc/pgx v3.3.0+incompatible
+)
+
+require (
+	cloud.google.com/go v0.30.0 // indirect
+	github.com/cockroachdb/apd v1.1.0 // indirect
+	github.com/go-aah/forge v0.8.0 // indirect
+	github.com/go-playground/locales v0.12.1 // indirect
+	github.com/go-playground/universal-translator v0.16.0 // indirect
+	github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee // indirect
+	github.com/gobwas/pool v0.2.0 // indirect
+	github.com/gobwas/ws v1.0.0 // indirect
+	github.com/golang/protobuf v1.3.1 // indirect
+	github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect
+	github.com/lib/pq v1.10.7 // indirect
 	github.com/pkg/errors v0.8.1 // indirect
+	github.com/satori/go.uuid v1.2.0 // indirect
+	github.com/shopspring/decimal v1.3.1 // indirect
+	github.com/urfave/cli v1.20.0 // indirect
+	golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 // indirect
+	golang.org/x/net v0.0.0-20190603091049-60506f45cf65 // indirect
+	golang.org/x/oauth2 v0.0.0-20181003184128-c57b0facaced // indirect
+	golang.org/x/sys v0.5.0 // indirect
+	google.golang.org/appengine v1.6.7 // indirect
+	gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
+	gopkg.in/go-playground/validator.v9 v9.21.0 // indirect
 )

+ 31 - 4
frameworks/Go/aah/src/benchmark/go.sum

@@ -1,7 +1,10 @@
-aahframe.work v0.12.2 h1:8JaLoaEzSR7J4Hk4zFcquM8Nz8aUtKOeODHzmc91o68=
-aahframe.work v0.12.2/go.mod h1:Ogn3OQKcq9W59XSAZzPqk4g2PpFH9h2Px1PFPnoGmvs=
+aahframe.work v0.12.4 h1:Hcp1EP7T8Y+qh1ukFjTqXjImqKxyk03nuvACm81OTfU=
+aahframe.work v0.12.4/go.mod h1:Ogn3OQKcq9W59XSAZzPqk4g2PpFH9h2Px1PFPnoGmvs=
 cloud.google.com/go v0.30.0 h1:xKvyLgk56d0nksWq49J0UyGEeUIicTl4+UBiX1NPX9g=
 cloud.google.com/go v0.30.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
+github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/go-aah/forge v0.8.0 h1:sk4Z523B9ay3JQF4At97U7kecB5yTIm0J2UM/qRVXbQ=
 github.com/go-aah/forge v0.8.0/go.mod h1:+pz2ywtYKCMzKtHa2kyKIOBw2XhQpj+dgch/vMGWyqo=
@@ -17,19 +20,43 @@ github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
 github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
 github.com/gobwas/ws v1.0.0 h1:1WdyfgUcImUfVBvYbsW2krIsnko+1QU2t45soaF8v1M=
 github.com/gobwas/ws v1.0.0/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
+github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=
+github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
 github.com/jackc/pgx v3.3.0+incompatible h1:Wa90/+qsITBAPkAZjiByeIGHFcj3Ztu+VzrrIpHjL90=
 github.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
+github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
+github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
+github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
+github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
+github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
 github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
-golang.org/x/crypto v0.0.0-20181012144002-a92615f3c490 h1:va0qYsIOza3Nlf2IncFyOql4/3XUq3vfge/Ad64bhlM=
 golang.org/x/crypto v0.0.0-20181012144002-a92615f3c490/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/net v0.0.0-20181201002055-351d144fa1fc h1:a3CU5tJYVj92DY2LaA1kUkrsqD5/3mLDhx2NcNqyW+0=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/oauth2 v0.0.0-20181003184128-c57b0facaced h1:4oqSq7eft7MdPKBGQK11X9WYUxmj6ZLgGTqYIbY1kyw=
 golang.org/x/oauth2 v0.0.0-20181003184128-c57b0facaced/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
+google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
+gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
 gopkg.in/go-playground/validator.v9 v9.21.0 h1:wSDJGBpQBYC1wLpVnGHLmshm2JicoSNdrb38Zj+8yHI=
 gopkg.in/go-playground/validator.v9 v9.21.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=

+ 3 - 1
frameworks/Go/fiber/fiber-prefork.dockerfile

@@ -1,9 +1,11 @@
-FROM docker.io/golang:1.19
+FROM docker.io/golang:1.20
 
 WORKDIR /fiber
 
 COPY ./src /fiber
 
+RUN go mod download
+
 RUN go generate -x ./templates
 
 RUN GOAMD64=v3 go build -ldflags="-s -w" -o app .

+ 1 - 1
frameworks/Go/fiber/fiber.dockerfile

@@ -1,4 +1,4 @@
-FROM docker.io/golang:1.19
+FROM docker.io/golang:1.20
 
 WORKDIR /fiber
 

+ 15 - 13
frameworks/Go/fiber/src/go.mod

@@ -3,26 +3,28 @@ module fiber/app
 go 1.19
 
 require (
-	github.com/gofiber/fiber/v2 v2.25.0
-	github.com/jackc/pgx/v4 v4.14.1
+	github.com/goccy/go-json v0.10.0
+	github.com/gofiber/fiber/v2 v2.41.0
+	github.com/jackc/pgx/v5 v5.2.0
 	github.com/valyala/quicktemplate v1.7.0
 )
 
 require (
 	github.com/andybalholm/brotli v1.0.4 // indirect
-	github.com/jackc/chunkreader/v2 v2.0.1 // indirect
-	github.com/jackc/pgconn v1.10.1 // indirect
-	github.com/jackc/pgio v1.0.0 // indirect
 	github.com/jackc/pgpassfile v1.0.0 // indirect
-	github.com/jackc/pgproto3/v2 v2.2.0 // indirect
 	github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
-	github.com/jackc/pgtype v1.9.1 // indirect
-	github.com/jackc/puddle v1.2.1 // indirect
-	github.com/klauspost/compress v1.14.1 // indirect
+	github.com/jackc/puddle/v2 v2.1.2 // indirect
+	github.com/klauspost/compress v1.15.9 // indirect
+	github.com/mattn/go-colorable v0.1.13 // indirect
+	github.com/mattn/go-isatty v0.0.17 // indirect
+	github.com/mattn/go-runewidth v0.0.14 // indirect
+	github.com/rivo/uniseg v0.2.0 // indirect
 	github.com/valyala/bytebufferpool v1.0.0 // indirect
-	github.com/valyala/fasthttp v1.32.0 // indirect
+	github.com/valyala/fasthttp v1.43.0 // indirect
 	github.com/valyala/tcplisten v1.0.0 // indirect
-	golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce // indirect
-	golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
-	golang.org/x/text v0.3.7 // indirect
+	go.uber.org/atomic v1.10.0 // indirect
+	golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect
+	golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 // indirect
+	golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
+	golang.org/x/text v0.3.8 // indirect
 )

+ 38 - 166
frameworks/Go/fiber/src/go.sum

@@ -1,205 +1,77 @@
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
 github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
 github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
 github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
 github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
-github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
-github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
-github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
-github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
-github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
-github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
-github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-github.com/gofiber/fiber/v2 v2.25.0 h1:kv8dmG/sAFDFpTueCMEn4X0JS5d72pEFTKLZ3miOREw=
-github.com/gofiber/fiber/v2 v2.25.0/go.mod h1:7efVWcBOZi1PyMWznnbitjnARPA7nYZxmQXJVod0bo0=
-github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
-github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
+github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/gofiber/fiber/v2 v2.41.0 h1:YhNoUS/OTjEz+/WLYuQ01xI7RXgKEFnGBKMagAu5f0M=
+github.com/gofiber/fiber/v2 v2.41.0/go.mod h1:RdebcCuCRFp4W6hr3968/XxwJVg0K+jr9/Ae0PFzZ0Q=
 github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
-github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
-github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
-github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
-github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
-github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
-github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
-github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
-github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
-github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
-github.com/jackc/pgconn v1.10.1 h1:DzdIHIjG1AxGwoEEqS+mGsURyjt4enSmqzACXvVzOT8=
-github.com/jackc/pgconn v1.10.1/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
-github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
-github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
-github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
-github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
-github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc=
-github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=
 github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
 github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
-github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
-github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
-github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
-github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
-github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
-github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
-github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
-github.com/jackc/pgproto3/v2 v2.2.0 h1:r7JypeP2D3onoQTCxWdTpCtJ4D+qpKr0TxvoyMhZ5ns=
-github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
 github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
 github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
-github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
-github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
-github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
-github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
-github.com/jackc/pgtype v1.9.1 h1:MJc2s0MFS8C3ok1wQTdQxWuXQcB6+HwAm5x1CzW7mf0=
-github.com/jackc/pgtype v1.9.1/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
-github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
-github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
-github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
-github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
-github.com/jackc/pgx/v4 v4.14.1 h1:71oo1KAGI6mXhLiTMn6iDFcp3e7+zon/capWjl2OEFU=
-github.com/jackc/pgx/v4 v4.14.1/go.mod h1:RgDuE4Z34o7XE92RpLsvFiOEfrAUT0Xt2KxvX73W06M=
-github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
-github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
-github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
-github.com/jackc/puddle v1.2.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
-github.com/jackc/puddle v1.2.1 h1:gI8os0wpRXFd4FiAY2dWiqRK037tjj3t7rKFeO4X5iw=
-github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
-github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/jackc/pgx/v5 v5.2.0 h1:NdPpngX0Y6z6XDFKqmFQaE+bCtkqzvQIOt1wvBlAqs8=
+github.com/jackc/pgx/v5 v5.2.0/go.mod h1:Ptn7zmohNsWEsdxRawMzk3gaKma2obW+NWTnKa0S4nk=
+github.com/jackc/puddle/v2 v2.1.2 h1:0f7vaaXINONKTsxYDn4otOAiJanX/BMeAtY//BXqzlg=
+github.com/jackc/puddle/v2 v2.1.2/go.mod h1:2lpufsF5mRHO6SuZkm0fNYxM6SWHfvyFj62KwNzgels=
 github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
 github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
-github.com/klauspost/compress v1.14.1 h1:hLQYb23E8/fO+1u53d02A97a8UnsddcvYzq4ERRU4ds=
-github.com/klauspost/compress v1.14.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
-github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
-github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
-github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
-github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
-github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
-github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
-github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
-github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
-github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
-github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY=
+github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
+github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
+github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
-github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
-github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
-github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
-github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
-github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
-github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
-github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
-github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
-github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
-github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
 github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus=
-github.com/valyala/fasthttp v1.32.0 h1:keswgWzyKyNIIjz2a7JmCYHOOIkRp6HMx9oTV6QrZWY=
-github.com/valyala/fasthttp v1.32.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus=
+github.com/valyala/fasthttp v1.43.0 h1:Gy4sb32C98fbzVWZlTM1oTMdLWGyvxR03VhM6cBIU4g=
+github.com/valyala/fasthttp v1.43.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY=
 github.com/valyala/quicktemplate v1.7.0 h1:LUPTJmlVcb46OOUY3IeD9DojFpAVbsG+5WFTcjMJzCM=
 github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8=
 github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
 github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
-github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
-go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
-go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
-go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
-go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
-go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
-go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
-go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
-go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
-go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
-go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
-go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
-golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
+go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
 golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
-golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce h1:Roh6XWxHFKrPgC/EQhVubSAGQ6Ozk6IdxHSzt1mR0EI=
-golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
-golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
+golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
+golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 h1:ZrnxWX62AgTKOSagEqxvb3ffipvEDX2pl7E1TdqLqIc=
+golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
-golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
+golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
-gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

+ 8 - 4
frameworks/Go/fiber/src/server.go

@@ -10,11 +10,13 @@ import (
 	"sort"
 	"sync"
 
+	"github.com/goccy/go-json"
+	"github.com/gofiber/fiber/v2"
+
 	"fiber/app/templates"
 
-	"github.com/gofiber/fiber/v2"
-	pgx "github.com/jackc/pgx/v4"
-	"github.com/jackc/pgx/v4/pgxpool"
+	"github.com/jackc/pgx/v5"
+	"github.com/jackc/pgx/v5/pgxpool"
 )
 
 var (
@@ -47,6 +49,8 @@ func main() {
 		StrictRouting:            true,
 		DisableHeaderNormalizing: true,
 		ServerHeader:             "go",
+		JSONEncoder:              json.Marshal,
+		JSONDecoder:              json.Unmarshal,
 	}
 
 	for i := range os.Args[1:] {
@@ -157,7 +161,7 @@ func initDatabase() {
 	}
 
 	var err error
-	db, err = pgxpool.Connect(context.Background(),
+	db, err = pgxpool.New(context.Background(),
 		fmt.Sprintf(
 			"host=%s port=%d user=%s password=%s dbname=%s pool_max_conns=%d",
 			"tfb-database", 5432,

+ 6 - 0
frameworks/Go/fiber/src/server_test.go

@@ -1,11 +1,13 @@
 package main
 
 import (
+	"encoding/json"
 	"io/ioutil"
 	"net/http"
 	"net/http/httptest"
 	"testing"
 
+	"github.com/goccy/go-json"
 	"github.com/gofiber/fiber/v2"
 	"github.com/gofiber/fiber/v2/utils"
 )
@@ -14,6 +16,8 @@ import (
 func Benchmark_Plaintext(b *testing.B) {
 	app := fiber.New(fiber.Config{
 		DisableStartupMessage: true,
+		JSONEncoder:           json.Marshal,
+		JSONDecoder:           json.Unmarshal,
 	})
 
 	app.Get("/plaintext", plaintextHandler)
@@ -41,6 +45,8 @@ func Benchmark_Plaintext(b *testing.B) {
 func Benchmark_JSON(b *testing.B) {
 	app := fiber.New(fiber.Config{
 		DisableStartupMessage: true,
+		JSONEncoder:           json.Marshal,
+		JSONDecoder:           json.Unmarshal,
 	})
 
 	app.Get("/json", jsonHandler)

+ 1 - 1
frameworks/Java/micronaut/gradle.properties

@@ -1 +1 @@
-micronautVersion = 3.8.2
+micronautVersion = 3.8.3

+ 0 - 21
frameworks/Java/redkale/benchmark_config.json

@@ -73,27 +73,6 @@
                 "display_name": "redkale-native",
                 "notes": "",
                 "versus": "Redkale"
-            },
-            "mysql": {
-                "db_url": "/db",
-                "query_url": "/queries?q=", 
-                "fortune_url": "/fortunes",
-                "update_url": "/updates?q=",
-                "port": 8080,
-                "approach": "Realistic",
-                "classification": "Fullstack",
-                "database": "MySQL",
-                "framework": "Redkale",
-                "language": "Java",
-                "flavor": "None",
-                "orm": "Raw",
-                "platform": "Redkale",
-                "webserver": "Redkale",
-                "os": "Linux",
-                "database_os": "Linux",
-                "display_name": "redkale-mysql",
-                "notes": "",
-                "versus": "Redkale"
             }
         }
     ]

+ 0 - 3
frameworks/Java/redkale/conf/application.xml

@@ -2,10 +2,7 @@
 
 <application port="8585">     
     
-    <executor threads="0"/>
-    
     <properties>    
-        <property name="system.property.redkale.convert.tiny" value="false"/>    
         <property name="system.property.redkale.http.request.pipeline.sameheaders" value="true"/>  
         <property name="system.property.redkale.http.response.header.server" value="redkale"/>
         <property name="system.property.redkale.http.response.header.connection" value="none"/>

+ 0 - 8
frameworks/Java/redkale/conf/source-mysql.properties

@@ -1,8 +0,0 @@
-
-
-############ DataSource ############
-redkale.datasource[].url = jdbc:mysql://tfb-database:3306/hello_world?useSSL=false&rewriteBatchedStatements=true&serverTimezone=UTC&characterEncoding=utf8
-redkale.datasource[].user = benchmarkdbuser
-redkale.datasource[].password = benchmarkdbpass
-redkale.datasource[].warnslowms = 0
-redkale.datasource[].errorslowms = 0

+ 0 - 15
frameworks/Java/redkale/config.toml

@@ -54,18 +54,3 @@ orm = "Raw"
 platform = "Redkale"
 webserver = "Redkale"
 versus = "Redkale"
-
-[mysql]
-urls.db = "/db"
-urls.fortune = "/fortunes"
-urls.query = "/queries?q="
-urls.update = "/updates?q="
-approach = "Realistic"
-classification = "Fullstack"
-database = "MySQL"
-database_os = "Linux"
-os = "Linux"
-orm = "Raw"
-platform = "Redkale"
-webserver = "Redkale"
-versus = "Redkale"

+ 0 - 12
frameworks/Java/redkale/redkale-mysql.dockerfile

@@ -1,12 +0,0 @@
-FROM maven:3.8.6-openjdk-18-slim as maven
-WORKDIR /redkale
-COPY src src
-COPY conf conf
-RUN rm conf/source.properties
-RUN mv conf/source-mysql.properties  conf/source.properties
-COPY pom.xml pom.xml
-RUN mvn package -q
-
-EXPOSE 8080
-
-CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-XX:AutoBoxCacheMax=80000", "-DAPP_HOME=./", "-jar", "/redkale/target/redkale-benchmark-1.0.0.jar"]

+ 29 - 5
frameworks/Java/redkale/src/main/java/org/redkalex/benchmark/BenchmarkService.java

@@ -7,8 +7,9 @@ package org.redkalex.benchmark;
 
 import java.util.*;
 import java.util.concurrent.*;
+import java.util.function.IntFunction;
 import java.util.stream.IntStream;
-import org.redkale.annotation.Resource;
+import org.redkale.annotation.*;
 import org.redkale.net.http.*;
 import org.redkale.service.AbstractService;
 import org.redkale.source.DataSource;
@@ -18,6 +19,7 @@ import org.redkale.util.AnyValue;
  *
  * @author zhangjx
  */
+@NonBlocking
 @RestService(name = " ", repair = false)
 public class BenchmarkService extends AbstractService {
 
@@ -26,9 +28,11 @@ public class BenchmarkService extends AbstractService {
     @Resource
     private DataSource source;
 
+    private WorldCache cache;
+
     @Override
     public void init(AnyValue conf) {
-        CachedWorld.Cache.getInstance(source);
+        this.cache = new WorldCache(source);
     }
 
     @RestMapping(name = "plaintext")
@@ -59,7 +63,7 @@ public class BenchmarkService extends AbstractService {
         IntStream ids = ThreadLocalRandom.current().ints(size, 1, 10001);
         int[] newNumbers = ThreadLocalRandom.current().ints(size, 1, 10001).toArray();
         return source.findsListAsync(World.class, ids.boxed())
-            .thenCompose(words -> source.updateAsync(World.setNewNumbers(words.toArray(new World[words.size()]), newNumbers))
+            .thenCompose(words -> source.updateAsync(World.updateNewNumbers(words, newNumbers))
             .thenApply(v -> words));
     }
 
@@ -73,8 +77,28 @@ public class BenchmarkService extends AbstractService {
     }
 
     @RestMapping(name = "cached-worlds")
-    public CachedWorld[] cachedWorlds(int q) {
+    public World[] cachedWorlds(int q) {
         int size = Math.min(500, Math.max(1, q));
-        return CachedWorld.Cache.getInstance(source).random(ThreadLocalRandom.current(), size);
+        return cache.random(size);
+    }
+
+    static class WorldCache {
+
+        private final IntFunction<World[]> arrayFunc = c -> new World[c];
+
+        private final World[] array;
+
+        private final IntFunction<World> mapFunc;
+
+        public WorldCache(DataSource source) {
+            List<World> list = source.queryList(World.class);
+            this.array = list.toArray(new World[list.size()]);
+            this.mapFunc = c -> array[c];
+        }
+
+        public World[] random(int size) {
+            IntStream ids = ThreadLocalRandom.current().ints(size, 0, 10000);
+            return ids.mapToObj(mapFunc).toArray(arrayFunc);
+        }
     }
 }

+ 0 - 85
frameworks/Java/redkale/src/main/java/org/redkalex/benchmark/CachedWorld.java

@@ -1,85 +0,0 @@
-package org.redkalex.benchmark;
-
-import java.util.*;
-import java.util.function.IntFunction;
-import java.util.stream.IntStream;
-import org.redkale.convert.json.JsonConvert;
-import org.redkale.persistence.*;
-import org.redkale.source.DataSource;
-
-/**
- *
- * @author zhangjx
- */
-@Entity
-@Table(name = "World")
-public final class CachedWorld implements Comparable<CachedWorld> {
-
-    @Id
-    private int id;
-
-    private int randomNumber;
-
-    public CachedWorld randomNumber(int randomNumber) {
-        this.randomNumber = randomNumber;
-        return this;
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public int getRandomNumber() {
-        return randomNumber;
-    }
-
-    public void setRandomNumber(int randomNumber) {
-        this.randomNumber = randomNumber;
-    }
-
-    @Override
-    public int compareTo(CachedWorld o) {
-        return Integer.compare(id, o.id);
-    }
-
-    @Override
-    public String toString() {
-        return JsonConvert.root().convertTo(this);
-    }
-
-    public static class Cache {
-
-        private static Cache instance;
-
-        static Cache getInstance(DataSource source) {
-            if (instance == null) {
-                synchronized (Cache.class) {
-                    if (instance == null) {
-                        instance = new Cache(source);
-                    }
-                }
-            }
-            return instance;
-        }
-
-        private CachedWorld[] array;
-
-        private IntFunction<CachedWorld> mapFunc = c -> array[c];
-
-        private IntFunction<CachedWorld[]> arrayFunc = c -> new CachedWorld[c];
-
-        public Cache(DataSource source) {
-            List<CachedWorld> list = source.queryList(CachedWorld.class);
-            this.array = list.toArray(new CachedWorld[list.size()]);
-        }
-
-        public CachedWorld[] random(Random random, int size) {
-            IntStream ids = random.ints(size, 0, 10000);
-            return ids.mapToObj(mapFunc).toArray(arrayFunc);
-        }
-    }
-}

+ 4 - 7
frameworks/Java/redkale/src/main/java/org/redkalex/benchmark/World.java

@@ -5,7 +5,7 @@
  */
 package org.redkalex.benchmark;
 
-import java.util.Arrays;
+import java.util.*;
 import org.redkale.convert.json.JsonConvert;
 import org.redkale.persistence.*;
 
@@ -21,13 +21,10 @@ public final class World implements Comparable<World> {
 
     private int randomNumber;
 
-    public World randomNumber(int randomNumber) {
-        this.randomNumber = randomNumber;
-        return this;
-    }
-
-    public static World[] setNewNumbers(World[] worlds, int[] newNumbers) {
+    public static World[] updateNewNumbers(List<World> list, int[] newNumbers) {
+        World[] worlds = new World[list.size()];
         for (int i = 0; i < worlds.length; i++) {
+            worlds[i] = list.get(i);
             worlds[i].randomNumber = newNumbers[i];
         }
         Arrays.sort(worlds);

+ 2 - 2
frameworks/Java/spring-webflux/spring-webflux-jdbc.dockerfile

@@ -1,10 +1,10 @@
-FROM maven:3.6.1-jdk-11-slim as maven
+FROM maven:3.8.5-openjdk-17-slim as maven
 WORKDIR /spring
 COPY src src
 COPY pom.xml pom.xml
 RUN mvn package -q
 
-FROM openjdk:11.0.3-jdk-slim
+FROM openjdk:17.0-jdk-slim
 WORKDIR /spring
 COPY --from=maven /spring/target/spring-webflux-benchmark.jar app.jar
 

+ 2 - 2
frameworks/Java/spring-webflux/spring-webflux-mongo.dockerfile

@@ -1,10 +1,10 @@
-FROM maven:3.6.1-jdk-11-slim as maven
+FROM maven:3.8.5-openjdk-17-slim as maven
 WORKDIR /spring
 COPY src src
 COPY pom.xml pom.xml
 RUN mvn package -q
 
-FROM openjdk:11.0.3-jdk-slim
+FROM openjdk:17.0-jdk-slim
 WORKDIR /spring
 COPY --from=maven /spring/target/spring-webflux-benchmark.jar app.jar
 

+ 2 - 2
frameworks/Java/spring-webflux/spring-webflux-pgclient.dockerfile

@@ -1,10 +1,10 @@
-FROM maven:3.6.1-jdk-11-slim as maven
+FROM maven:3.8.5-openjdk-17-slim as maven
 WORKDIR /spring
 COPY src src
 COPY pom.xml pom.xml
 RUN mvn package -q
 
-FROM openjdk:11.0.3-jdk-slim
+FROM openjdk:17.0-jdk-slim
 WORKDIR /spring
 COPY --from=maven /spring/target/spring-webflux-benchmark.jar app.jar
 

+ 2 - 2
frameworks/Java/spring-webflux/spring-webflux-rxjdbc.dockerfile

@@ -1,10 +1,10 @@
-FROM maven:3.6.1-jdk-11-slim as maven
+FROM maven:3.8.5-openjdk-17-slim as maven
 WORKDIR /spring
 COPY src src
 COPY pom.xml pom.xml
 RUN mvn package -q
 
-FROM openjdk:11.0.3-jdk-slim
+FROM openjdk:17.0-jdk-slim
 WORKDIR /spring
 COPY --from=maven /spring/target/spring-webflux-benchmark.jar app.jar
 

+ 2 - 2
frameworks/Java/spring-webflux/spring-webflux.dockerfile

@@ -1,10 +1,10 @@
-FROM maven:3.6.1-jdk-11-slim as maven
+FROM maven:3.8.5-openjdk-17-slim as maven
 WORKDIR /spring
 COPY src src
 COPY pom.xml pom.xml
 RUN mvn package -q
 
-FROM openjdk:11.0.3-jdk-slim
+FROM openjdk:17.0-jdk-slim
 WORKDIR /spring
 COPY --from=maven /spring/target/spring-webflux-benchmark.jar app.jar
 

+ 10 - 45
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<String> lines = template.readLines().collect { it.trim() }
-        template.write(lines.join(""))
-    }
-}
-
-assemble.dependsOn("minimizeTemplate")

+ 34 - 0
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<String> 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)
+        }
+    }
+}

+ 27 - 0
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)
+    }
+}

+ 12 - 13
frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt → 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 {

+ 4 - 3
frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt → 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!",

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


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


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


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


+ 0 - 0
frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkStore.kt → frameworks/Kotlin/hexagon/core/src/main/kotlin/store/BenchmarkStore.kt


+ 0 - 0
frameworks/Kotlin/hexagon/src/main/resources/fortunes.pebble.html → frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.pebble.html


+ 24 - 0
frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.rocker.html

@@ -0,0 +1,24 @@
+@import java.util.*
+@import com.hexagonkt.model.Fortune
+@args(Map<String, Object> context)
+<!DOCTYPE html>
+
+<html>
+<head>
+  <title>Fortunes</title>
+</head>
+<body>
+<table>
+  <tr>
+    <th>id</th>
+    <th>message</th>
+  </tr>
+  @for ((fortune) : (Collection<Fortune>)context.get("fortunes")) {
+  <tr>
+    <td>@fortune.getId()</td>
+    <td>@fortune.getMessage()</td>
+  </tr>
+  }
+</table>
+</body>
+</html>

+ 5 - 8
frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile

@@ -5,22 +5,19 @@ 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
 

+ 5 - 8
frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile

@@ -5,22 +5,19 @@ 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
 

+ 6 - 9
frameworks/Kotlin/hexagon/hexagon-netty.dockerfile

@@ -5,22 +5,19 @@ 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
+FROM eclipse-temurin:17-jre-alpine
 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
+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
 

+ 6 - 9
frameworks/Kotlin/hexagon/hexagon-nettyepoll-pgclient.dockerfile

@@ -5,22 +5,19 @@ 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
+FROM eclipse-temurin:17-jre-alpine
 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
+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
 

+ 6 - 9
frameworks/Kotlin/hexagon/hexagon-nettyepoll.dockerfile

@@ -5,22 +5,19 @@ 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
+FROM eclipse-temurin:17-jre-alpine
 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
+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
 

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

@@ -5,18 +5,17 @@ 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

+ 6 - 9
frameworks/Kotlin/hexagon/hexagon.dockerfile

@@ -5,22 +5,19 @@ 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
+FROM eclipse-temurin:17-jre-alpine
 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
+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
 

+ 13 - 0
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")

+ 23 - 0
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()
+}

+ 13 - 0
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")

+ 23 - 0
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()
+}

+ 13 - 0
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")

+ 17 - 0
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()
+}

+ 14 - 0
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")

+ 17 - 0
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()
+}

+ 14 - 0
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")

+ 17 - 0
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()
+}

+ 15 - 0
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")
+}

+ 9 - 3
frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt → 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<HttpHandler> {
-            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)

+ 13 - 0
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",
+)

+ 0 - 56
frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt

@@ -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<String, HttpServerPort> 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<String, BenchmarkStore> by lazy {
-    mapOf(
-        "postgresql" to BenchmarkSqlStore("postgresql"),
-        "pg_client" to BenchmarkPgClientStore("postgresql"),
-    )
-}
-
-internal val server: HttpServer by lazy {
-    val engine = engines[settings.webEngine] ?: error("Unsupported server engine")
-    val 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()
-}

+ 6 - 0
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")
+}

+ 3 - 2
frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkPgClientStore.kt → 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 {

+ 6 - 0
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")
+}

+ 1 - 1
frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt → 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) {
 

+ 3 - 3
frameworks/Kotlin/http4k/build.gradle

@@ -1,6 +1,6 @@
 buildscript {
-    ext.kotlin_version = "1.7.22"
-    ext.http4k_version = "4.34.2.0"
+    ext.kotlin_version = "1.8.10"
+    ext.http4k_version = "4.37.0.0"
 
     repositories {
         mavenCentral()
@@ -28,5 +28,5 @@ allprojects {
     version = project.hasProperty('releaseVersion') ? project.releaseVersion : 'LOCAL'
     group = 'org.http4k'
 
-    compileTestKotlin.kotlinOptions.languageVersion = "1.7"
+    compileTestKotlin.kotlinOptions.languageVersion = "1.8"
 }

+ 1 - 1
frameworks/Kotlin/http4k/gradle/wrapper/gradle-wrapper.properties

@@ -1,5 +1,5 @@
 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
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists

+ 2 - 2
frameworks/Kotlin/http4k/http4k-apache-graalvm.dockerfile

@@ -1,4 +1,4 @@
-FROM gradle:7.6-jdk17 as gradle
+FROM gradle:7.6-jdk19 as gradle
 USER root
 WORKDIR /http4k
 COPY build.gradle build.gradle
@@ -26,7 +26,7 @@ RUN native-image \
     --initialize-at-build-time="org.slf4j.LoggerFactory,org.slf4j.simple.SimpleLogger,org.slf4j.impl.StaticLoggerBinder" \
     --no-fallback -cp http4k-benchmark.jar http4k.Http4kGraalVMBenchmarkServerKt
 
-FROM frolvlad/alpine-glibc
+FROM frolvlad/alpine-glibc:glibc-2.34
 RUN apk update && apk add libstdc++
 EXPOSE 9000
 COPY --from=graalvm /home/app/http4k-apache-graalvm/http4k.http4kgraalvmbenchmarkserverkt /app/http4k-apache-graalvm

+ 1 - 1
frameworks/Kotlin/http4k/http4k-apache.dockerfile

@@ -1,4 +1,4 @@
-FROM gradle:7.6-jdk17
+FROM gradle:7.6-jdk19
 USER root
 WORKDIR /http4k
 COPY build.gradle build.gradle

+ 1 - 1
frameworks/Kotlin/http4k/http4k-apache4.dockerfile

@@ -1,4 +1,4 @@
-FROM gradle:7.6-jdk17
+FROM gradle:7.6-jdk19
 USER root
 WORKDIR /http4k
 COPY build.gradle build.gradle

+ 2 - 2
frameworks/Kotlin/http4k/http4k-graalvm.dockerfile

@@ -1,4 +1,4 @@
-FROM gradle:7.6-jdk17 as gradle
+FROM gradle:7.6-jdk19 as gradle
 USER root
 WORKDIR /http4k
 COPY build.gradle build.gradle
@@ -26,7 +26,7 @@ RUN native-image \
     --initialize-at-build-time="org.slf4j.LoggerFactory,org.slf4j.simple.SimpleLogger,org.slf4j.impl.StaticLoggerBinder" \
     --no-fallback -cp http4k-benchmark.jar http4k.Http4kGraalVMBenchmarkServerKt
 
-FROM frolvlad/alpine-glibc
+FROM frolvlad/alpine-glibc:glibc-2.34
 RUN apk update && apk add libstdc++
 EXPOSE 9000
 COPY --from=graalvm /home/app/http4k-graalvm/http4k.http4kgraalvmbenchmarkserverkt /app/http4k-graalvm

+ 1 - 1
frameworks/Kotlin/http4k/http4k-jetty.dockerfile

@@ -1,4 +1,4 @@
-FROM gradle:7.6-jdk17
+FROM gradle:7.6-jdk19
 USER root
 WORKDIR /http4k
 COPY build.gradle build.gradle

+ 1 - 1
frameworks/Kotlin/http4k/http4k-ktorcio.dockerfile

@@ -1,4 +1,4 @@
-FROM gradle:7.6-jdk17
+FROM gradle:7.6-jdk19
 USER root
 WORKDIR /http4k
 COPY build.gradle build.gradle

+ 1 - 1
frameworks/Kotlin/http4k/http4k-ktornetty.dockerfile

@@ -1,4 +1,4 @@
-FROM gradle:7.6-jdk17
+FROM gradle:7.6-jdk19
 USER root
 WORKDIR /http4k
 COPY build.gradle build.gradle

+ 1 - 1
frameworks/Kotlin/http4k/http4k-netty.dockerfile

@@ -1,4 +1,4 @@
-FROM gradle:7.6-jdk17
+FROM gradle:7.6-jdk19
 USER root
 WORKDIR /http4k
 COPY build.gradle build.gradle

+ 1 - 1
frameworks/Kotlin/http4k/http4k-ratpack.dockerfile

@@ -1,4 +1,4 @@
-FROM gradle:7.6-jdk17
+FROM gradle:7.6-jdk19
 USER root
 WORKDIR /http4k
 COPY build.gradle build.gradle

+ 1 - 1
frameworks/Kotlin/http4k/http4k-undertow.dockerfile

@@ -1,4 +1,4 @@
-FROM gradle:7.6-jdk17
+FROM gradle:7.6-jdk19
 USER root
 WORKDIR /http4k
 COPY build.gradle build.gradle

+ 1 - 1
frameworks/Kotlin/http4k/http4k.dockerfile

@@ -1,4 +1,4 @@
-FROM gradle:7.6-jdk17
+FROM gradle:7.6-jdk19
 USER root
 WORKDIR /http4k
 COPY build.gradle build.gradle

+ 6 - 25
frameworks/Kotlin/http4k/jettyloom-jdbc/src/main/kotlin/JettyLoom.kt

@@ -1,5 +1,5 @@
-import org.eclipse.jetty.server.*
-import org.eclipse.jetty.util.thread.ThreadPool
+import org.eclipse.jetty.server.Server
+import org.eclipse.jetty.util.thread.QueuedThreadPool
 import org.http4k.core.HttpHandler
 import org.http4k.server.Http4kServer
 import org.http4k.server.ServerConfig
@@ -7,12 +7,12 @@ import org.http4k.server.ServerConfig.StopMode.Graceful
 import org.http4k.server.http
 import org.http4k.server.toJettyHandler
 import java.time.Duration.ofSeconds
-import java.util.concurrent.Executors
-import java.util.concurrent.TimeUnit.NANOSECONDS
-import kotlin.Long.Companion.MAX_VALUE
+import java.util.concurrent.Executors.newVirtualThreadPerTaskExecutor
 
 class JettyLoom(private val port: Int) : ServerConfig {
-    private val server = Server(LoomThreadPool())
+    private val server = Server(QueuedThreadPool().apply {
+        virtualThreadsExecutor = newVirtualThreadPerTaskExecutor()
+    })
 
     override val stopMode = Graceful(ofSeconds(5))
 
@@ -26,22 +26,3 @@ class JettyLoom(private val port: Int) : ServerConfig {
         }
     }
 }
-
-class LoomThreadPool : ThreadPool {
-    private val executorService = Executors.newVirtualThreadPerTaskExecutor()
-
-    @Throws(InterruptedException::class)
-    override fun join() {
-        executorService.awaitTermination(MAX_VALUE, NANOSECONDS)
-    }
-
-    override fun getThreads() = 1
-
-    override fun getIdleThreads() = 1
-
-    override fun isLowOnThreads() = false
-
-    override fun execute(command: Runnable) {
-        executorService.submit(command)
-    }
-}

+ 5 - 24
frameworks/Kotlin/http4k/jettyloom-pgclient/src/main/kotlin/JettyLoom.kt

@@ -1,5 +1,5 @@
-import org.eclipse.jetty.server.*
-import org.eclipse.jetty.util.thread.ThreadPool
+import org.eclipse.jetty.server.Server
+import org.eclipse.jetty.util.thread.QueuedThreadPool
 import org.http4k.core.HttpHandler
 import org.http4k.server.Http4kServer
 import org.http4k.server.ServerConfig
@@ -8,11 +8,11 @@ import org.http4k.server.http
 import org.http4k.server.toJettyHandler
 import java.time.Duration.ofSeconds
 import java.util.concurrent.Executors
-import java.util.concurrent.TimeUnit.NANOSECONDS
-import kotlin.Long.Companion.MAX_VALUE
 
 class JettyLoom(private val port: Int) : ServerConfig {
-    private val server = Server(LoomThreadPool())
+    private val server = Server(QueuedThreadPool().apply {
+        virtualThreadsExecutor = Executors.newVirtualThreadPerTaskExecutor()
+    })
 
     override val stopMode = Graceful(ofSeconds(5))
 
@@ -26,22 +26,3 @@ class JettyLoom(private val port: Int) : ServerConfig {
         }
     }
 }
-
-class LoomThreadPool : ThreadPool {
-    private val executorService = Executors.newVirtualThreadPerTaskExecutor()
-
-    @Throws(InterruptedException::class)
-    override fun join() {
-        executorService.awaitTermination(MAX_VALUE, NANOSECONDS)
-    }
-
-    override fun getThreads() = 1
-
-    override fun getIdleThreads() = 1
-
-    override fun isLowOnThreads() = false
-
-    override fun execute(command: Runnable) {
-        executorService.submit(command)
-    }
-}

+ 23 - 3
frameworks/Kotlin/http4k/undertow/src/main/kotlin/Http4kUndertowServer.kt

@@ -1,5 +1,25 @@
-import org.http4k.server.Undertow
+import io.undertow.server.handlers.BlockingHandler
+import org.http4k.core.HttpHandler
+import org.http4k.server.Http4kServer
+import org.http4k.server.Http4kUndertowHttpHandler
+import org.http4k.server.ServerConfig
 
 fun main() {
-    Http4kBenchmarkServer(PostgresDatabase()).start(Undertow(9000))
-}
+    Http4kBenchmarkServer(PostgresDatabase()).start(CustomUndertow(9000))
+}
+
+private fun CustomUndertow(port: Int) = object : ServerConfig {
+    override fun toServer(http: HttpHandler) = object : Http4kServer {
+        val server = io.undertow.Undertow.builder()
+            .addHttpListener(port, "0.0.0.0")
+            .setHandler(BlockingHandler(Http4kUndertowHttpHandler(http)))
+            .setWorkerThreads(32 * Runtime.getRuntime().availableProcessors())
+            .build()
+
+        override fun start() = apply { server.start() }
+
+        override fun stop() = apply { server.stop() }
+
+        override fun port() = port
+    }
+}

+ 2 - 2
frameworks/Pascal/mormot/setup_and_build.sh

@@ -40,7 +40,7 @@ echo "Unpacking to ./libs/mORMot/static ..."
 rm -rf ./mormot2static.7z
 
 # uncomment for fixed commit URL
-URL=https://github.com/synopse/mORMot2/tarball/dbe44a75014ac01f3afb4fbf1880dbfd18ae0d2c
+URL=https://github.com/synopse/mORMot2/tarball/7cc9e10d6dfbe531ded16aa7f9ccd0fb95f8c6dd
 #URL="https://api.github.com/repos/synopse/mORMot2/tarball/$USED_TAG"
 echo "Download and unpacking mORMot sources from $URL ..."
 wget -qO- "$URL" | tar -xz -C ./libs/mORMot  --strip-components=1
@@ -82,7 +82,7 @@ fpc -MDelphi -Sci -Ci -O3 -g -gl -gw2 -Xg -k'-rpath=$ORIGIN' -k-L$BIN \
   -Fu"$MSRC/core" -Fu"$MSRC/db" -Fu"$MSRC/rest" -Fu"$MSRC/crypt" \
     -Fu"$MSRC/app" -Fu"$MSRC/net" -Fu"$MSRC/lib" -Fu"$MSRC/orm" -Fu"$MSRC/soa" \
   -FU"$BIN/fpc-$ARCH_TG/.dcu" -FE"$BIN/fpc-$ARCH_TG" -o"$BIN/fpc-$ARCH_TG/$dest_fn" \
-  -dFPC_X64MM -dFPCMM_SERVER -dNOSYNDBZEOS -dNOSYNDBIBX -dFPCMM_REPORTMEMORYLEAKS \
+  -dFPC_LIBCMM -dNOSYNDBZEOS -dNOSYNDBIBX \
   -B -Se1 "./src/raw.pas" | grep "[Warning|Error|Fatal]:"
 
 script_successful

+ 7 - 6
frameworks/Pascal/mormot/src/raw.lpi

@@ -86,13 +86,12 @@
       </Debugging>
     </Linking>
     <Other>
-      <CustomOptions Value="-dFPC_X64MM
--dFPCMM_SERVER
--dFPCMM_REPORTMEMORYLEAKS
--dFPCMM_DEBUG
+      <CustomOptions Value="-dWITH_LOGS
 -dNOSYNDBZEOS
--dNOSYNDBIBX"/>
-      <OtherDefines Count="7">
+-dNOSYNDBIBX
+-dFPC_LIBCMM
+-dFPCMM_BOOSTER"/>
+      <OtherDefines Count="9">
         <Define0 Value="FPC_X64MM"/>
         <Define1 Value="FPCMM_SERVER"/>
         <Define2 Value="FPCMM_REPORTMEMORYLEAKS"/>
@@ -100,6 +99,8 @@
         <Define4 Value="WITH_LOGS"/>
         <Define5 Value="NOSYNDBZEOS"/>
         <Define6 Value="NOSYNDBIBX"/>
+        <Define7 Value="FPC_LIBCMM"/>
+        <Define8 Value="FPCMM_BOOSTER"/>
       </OtherDefines>
     </Other>
   </CompilerOptions>

+ 43 - 32
frameworks/Pascal/mormot/src/raw.pas

@@ -11,7 +11,7 @@ See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-
 // logging is fine for debugging, less for benchmarking ;)
 
 uses
-  {$I mormot.uses.inc} // include mormot.core.fpcx64mm
+  {$I mormot.uses.inc} // include mormot.core.fpcx64mm or mormot.core.fpclibcmm
   sysutils,
   classes,
   BaseUnix,
@@ -84,7 +84,7 @@ type
     fTemplate: TSynMustache;
   protected
     // as used by rawqueries and rawupdates
-    procedure getRawRandomWorlds(cnt: PtrInt; out res: TWorlds);
+    function getRawRandomWorlds(cnt: PtrInt; out res: TWorlds): boolean;
     // implements /queries and /cached-queries endpoints
     function doqueries(ctxt: THttpServerRequestAbstract; orm: TOrmWorldClass;
       const search: RawUtf8): cardinal;
@@ -111,11 +111,11 @@ const
   HELLO_WORLD: RawUtf8 = 'Hello, World!';
   WORLD_COUNT = 10000;
 
-  WORLD_READ_SQL = 'select id, randomNumber from World where id=?';
+  WORLD_READ_SQL = 'select id,randomNumber from World where id=?';
   WORLD_UPDATE_SQLN ='update World as t set randomNumber = v.r from ' +
-    '(SELECT unnest(?::NUMERIC[]), unnest(?::NUMERIC[]) order by 2) as v(id, r)' +
+    '(SELECT unnest(?::bigint[]), unnest(?::bigint[]) order by 1) as v(id, r)' +
     ' where t.id = v.id';
-  FORTUNES_SQL = 'select id, message from Fortune';
+  FORTUNES_SQL = 'select id,message from Fortune';
 
   FORTUNES_MESSAGE = 'Additional fortune added at request time.';
   FORTUNES_TPL = '<!DOCTYPE html>' +
@@ -224,8 +224,8 @@ begin
   stmt.ExecutePrepared;
   if stmt.Step then
   begin
-    ctxt.SetOutJson('{"id":%,"randomNumber":%}',
-      [stmt.ColumnInt(0), stmt.ColumnInt(1)]);
+    ctxt.SetOutJson(
+      '{"id":%,"randomNumber":%}', [stmt.ColumnInt(0), stmt.ColumnInt(1)]);
     result := HTTP_SUCCESS;
     stmt.ReleaseRows;
   end;
@@ -255,34 +255,47 @@ begin
   result := doqueries(ctxt, TOrmCachedWorld, 'COUNT=');
 end;
 
-procedure TRawAsyncServer.getRawRandomWorlds(cnt: PtrInt; out res: TWorlds);
+function TRawAsyncServer.getRawRandomWorlds(cnt: PtrInt; out res: TWorlds): boolean;
 var
   conn: TSqlDBConnection;
   stmt: ISQLDBStatement;
+  pConn: TSqlDBPostgresConnection absolute conn;
   pStmt: TSqlDBPostgresStatement;
   i: PtrInt;
 begin
+  result := false;
   SetLength(res{%H-}, cnt);
   conn := fDbPool.ThreadSafeConnection;
-  stmt := conn.NewStatementPrepared(WORLD_READ_SQL, true, true);
+  if not conn.IsConnected then
+    conn.Connect;
   // specific code to use PostgresSQL pipelining mode
-  TSqlDBPostgresConnection(conn).EnterPipelineMode;
+  // see test_nosync in
+  // https://github.com/postgres/postgres/blob/master/src/test/modules/libpq_pipeline/libpq_pipeline.c
+  stmt := conn.NewStatementPrepared(WORLD_READ_SQL, true, true);
+  //w/o transaction pg_stat_statements view returns calls-1 and tfb verify fails
+  conn.StartTransaction;
+  pConn.EnterPipelineMode;
   pStmt := (stmt as TSqlDBPostgresStatement);
   for i := 0 to cnt - 1 do
   begin
     stmt.Bind(1, RandomWorld);
     pStmt.SendPipelinePrepared;
+    pConn.Flush;
   end;
-  TSqlDBPostgresConnection(conn).PipelineSync;
+  pConn.SendFlushRequest;
+  pConn.Flush;
   for i := 0 to cnt - 1 do
   begin
-    pStmt.GetPipelineResult(i = 0);
+    pStmt.GetPipelineResult;
     if not stmt.Step then
       exit;
-    res[i].id := stmt.ColumnInt(0);
-    res[i].randomNumber := stmt.ColumnInt(1);
+    res[i].id := pStmt.ColumnInt(0);
+    res[i].randomNumber := pStmt.ColumnInt(1);
+    pStmt.ReleaseRows;
   end;
-  TSqlDBPostgresConnection(conn).ExitPipelineMode(true);
+  pConn.ExitPipelineMode;
+  conn.commit;
+  result := true;
 end;
 
 function TRawAsyncServer.rawqueries(ctxt: THttpServerRequestAbstract): cardinal;
@@ -291,8 +304,7 @@ var
   res: TWorlds;
 begin
   cnt := getQueriesParamValue(ctxt);
-  getRawRandomWorlds(cnt, res);
-  if res = nil then
+  if not getRawRandomWorlds(cnt, res) then
     exit(HTTP_SERVERERROR);
   ctxt.SetOutJson(SaveJson(res, TypeInfo(TWorlds)));
   result := HTTP_SUCCESS;
@@ -361,9 +373,9 @@ var
   conn: TSqlDBConnection;
   stmt: ISQLDBStatement;
   list: TFortunes;
-  f: TFortune;
   arr: TDynArray;
   n: integer;
+  f: ^TFortune;
 begin
   conn := fDbPool.ThreadSafeConnection;
   stmt := conn.NewStatementPrepared(FORTUNES_SQL, true, true);
@@ -371,13 +383,13 @@ begin
   arr.Init(TypeInfo(TFortunes), list, @n);
   while stmt.Step do
   begin
+    f := arr.NewPtr;
     f.id := stmt.ColumnInt(0);
     f.message := stmt.ColumnUtf8(1);
-    arr.Add(f);
   end;
+  f := arr.NewPtr;
   f.id := 0;
   f.message := FORTUNES_MESSAGE;
-  arr.Add(f);
   arr.Sort(FortuneCompareByMessage);
   ctxt.OutContent := fTemplate.RenderDataArray(arr);
   ctxt.OutContentType := HTML_CONTENT_TYPE;
@@ -425,12 +437,13 @@ var
   conn: TSqlDBConnection;
   stmt: ISQLDBStatement;
 begin
+  result := HTTP_SERVERERROR;
+  conn := fDbPool.ThreadSafeConnection;
   cnt := getQueriesParamValue(ctxt);
-  getRawRandomWorlds(cnt, words);
-  if length(words) <> cnt then
-    exit(HTTP_SERVERERROR);
-  setLength(ids, cnt);
-  setLength(nums, cnt);
+  if not getRawRandomWorlds(cnt, words) then
+    exit;
+  setLength(ids{%H-}, cnt);
+  setLength(nums{%H-}, cnt);
   // generate new randoms, fill parameters arrays for update
   for i := 0 to cnt - 1 do
   begin
@@ -438,13 +451,11 @@ begin
     ids[i] := words[i].id;
     nums[i] := words[i].randomNumber;
   end;
-  conn := fDbPool.ThreadSafeConnection;
-  //conn.StartTransaction;
   stmt := conn.NewStatementPrepared(WORLD_UPDATE_SQLN, false, true);
-  stmt.BindArray(1, nums);
-  stmt.BindArray(2, ids);
+  stmt.BindArray(1, ids);
+  stmt.BindArray(2, nums);
   stmt.ExecutePrepared;
-  //conn.Commit; // autocommit
+  //conn.Commit;
   ctxt.SetOutJson(SaveJson(words, TypeInfo(TWorlds)));
   result := HTTP_SUCCESS;
 end;
@@ -475,8 +486,8 @@ begin
     // user specified some values at command line
     if not TryStrToInt(ParamStr(1), threads) then
       threads := SystemInfo.dwNumberOfProcessors * 4;
-    if threads < 4 then
-      threads := 4
+    if threads < 2 then
+      threads := 2
     else if threads > 256 then
       threads := 256; // max. threads for THttpAsyncServer
 

+ 1 - 1
frameworks/Python/eve/requirements.txt

@@ -5,4 +5,4 @@ gunicorn==19.9.0
 itsdangerous==0.24
 meinheld==0.6.1
 uWSGI==2.0.17.1
-Werkzeug==0.15.3
+Werkzeug==0.15.5

+ 6 - 2
frameworks/Ruby/h2o_mruby/README.md

@@ -2,8 +2,12 @@
 
 This is a framework implementation using the [H2O](https://h2o.examp1e.net/) HTTP server
 and the [mruby](https://mruby.org/) implementation of the [Ruby](https://www.ruby-lang.org/)
-language.
+programming language.
 
 ## Requirements
 
-H2O
+[H2O](https://h2o.examp1e.net/)
+
+## Test implementations
+
+The test implementations are located inline into the [h2o.conf](h2o.conf) configuration file.

+ 24 - 13
frameworks/Ruby/h2o_mruby/h2o_mruby.dockerfile

@@ -1,20 +1,31 @@
-FROM ruby:2.6
+ARG RUBY_IMAGE_VERSION=3.2
 
-ADD ./h2o.conf ./
+ARG H2O_PREFIX=/opt/h2o
 
-RUN apt-get update && apt-get install -yqq bison cmake libssl-dev make
+FROM ruby:${RUBY_IMAGE_VERSION} AS compile
 
-ENV H2O_VERSION=2.3.0-beta2
-ENV H2O_ARCHIVE="v${H2O_VERSION}.tar.gz"
-ENV H2O_HOME=/h2o
+ARG H2O_VERSION=9ab3feb4d7429ddda52a3cf84bd6da0e890bd52a
 
-RUN wget -q "https://github.com/h2o/h2o/archive/$H2O_ARCHIVE" && \
-    tar xf "$H2O_ARCHIVE" && \
-    cd "h2o-$H2O_VERSION" && \
-    cmake -DCMAKE_INSTALL_PREFIX="$H2O_HOME" -DCMAKE_C_FLAGS="-flto -march=native" \
-          -DCMAKE_AR=/usr/bin/gcc-ar -DCMAKE_RANLIB=/usr/bin/gcc-ranlib -DWITH_MRUBY=on . && \
-    make -j "$(nproc)" install
+ARG DEBIAN_FRONTEND=noninteractive
+RUN apt-get -yqq update && apt-get -yqq install cmake ninja-build
+WORKDIR h2o-build
+ARG H2O_ARCHIVE="${H2O_VERSION}.tar.gz"
+ADD "https://github.com/h2o/h2o/archive/${H2O_ARCHIVE}" ./
+RUN tar --strip-components=1 -xf "${H2O_ARCHIVE}"
+ARG H2O_PREFIX
+WORKDIR build
+RUN cmake -G Ninja -DCMAKE_C_FLAGS="-flto -march=native -mtune=native" -DWITH_MRUBY=on \
+          -DCMAKE_AR=/usr/bin/gcc-ar -DCMAKE_RANLIB=/usr/bin/gcc-ranlib \
+          -DCMAKE_INSTALL_PREFIX="${H2O_PREFIX}" .. && \
+    cmake --build . -j && \
+    cmake --install .
+WORKDIR /
 
+FROM ruby:${RUBY_IMAGE_VERSION}-slim
+
+ARG H2O_PREFIX
+ADD ./h2o.conf "${H2O_PREFIX}/"
+COPY --from=compile "${H2O_PREFIX}" "${H2O_PREFIX}/"
 EXPOSE 8080
 
-CMD "${H2O_HOME}/bin/h2o" -c h2o.conf
+CMD ["/opt/h2o/bin/h2o", "-c", "/opt/h2o/h2o.conf"]

+ 19 - 0
frameworks/Rust/anansi/Cargo.toml

@@ -0,0 +1,19 @@
+[workspace]
+members = [
+    ".",
+]
+
+[package]
+name = "tfb-anansi"
+version = "0.1.0"
+edition = "2021"
+
+[features]
+raw = []
+
+[dependencies]
+anansi = { git = "https://github.com/saru-tora/anansi", rev = "2567157", features = ["postgres", "minimal", "redis"] }
+async-trait = "0.1.57"
+rand = "0.8.4"
+serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"

+ 36 - 0
frameworks/Rust/anansi/README.md

@@ -0,0 +1,36 @@
+# [Anansi](https://saru-tora.github.io/anansi/) Benchmarking Test
+
+Anansi is a simple full-stack web framework for Rust.
+
+### Test Type Implementation Source Code
+
+All tests can be found in: src/hello/world/
+
+## Test URLs
+### JSON
+
+http://localhost:8080/json
+
+### PLAINTEXT
+
+http://localhost:8080/plaintext
+
+### DB
+
+http://localhost:8080/db
+
+### QUERY
+
+http://localhost:8080/query?queries=
+
+### CACHED QUERY
+
+http://localhost:8080/cached_query?queries=
+
+### UPDATE
+
+http://localhost:8080/update?queries=
+
+### FORTUNES
+
+http://localhost:8080/fortunes

+ 11 - 0
frameworks/Rust/anansi/anansi-raw.dockerfile

@@ -0,0 +1,11 @@
+FROM rust:1.64
+
+ADD ./ /anansi
+WORKDIR /anansi
+
+RUN cargo clean
+RUN RUSTFLAGS="-C target-cpu=native" cargo build --release --features raw
+
+EXPOSE 8080
+
+CMD RUST_LOG=off ./target/release/tfb-anansi 0.0.0.0:8080

+ 14 - 0
frameworks/Rust/anansi/anansi.dockerfile

@@ -0,0 +1,14 @@
+FROM rust:1.64
+
+RUN apt-get update -yqq && apt-get install -yqq --no-install-recommends redis-server
+
+ADD ./ /anansi
+WORKDIR /anansi
+
+RUN cargo clean
+RUN RUSTFLAGS="-C target-cpu=native" cargo build --release
+
+EXPOSE 8080
+
+ENV RUST_LOG=off
+CMD service redis-server start && ./target/release/tfb-anansi 0.0.0.0:8080

+ 52 - 0
frameworks/Rust/anansi/benchmark_config.json

@@ -0,0 +1,52 @@
+{
+  "framework": "anansi",
+  "tests": [
+    {
+      "default": {
+        "json_url": "/json",
+        "plaintext_url": "/plaintext",
+        "db_url": "/db",
+        "fortune_url": "/fortunes",
+        "query_url": "/queries?q=",
+        "update_url": "/updates?q=",
+        "cached_query_url": "/cached-queries?q=",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Fullstack",
+        "database": "postgres",
+        "framework": "Anansi",
+        "language": "Rust",
+        "flavor": "None",
+        "orm": "Full",
+        "platform": "None",
+        "webserver": "hyper",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "Anansi",
+        "notes": "",
+        "versus": "None"
+      },
+      "raw": {
+        "db_url": "/db",
+        "fortune_url": "/fortunes",
+        "query_url": "/queries?q=",
+        "update_url": "/updates?q=",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Fullstack",
+        "database": "postgres",
+        "framework": "Anansi",
+        "language": "Rust",
+        "flavor": "None",
+        "orm": "Raw",
+        "platform": "None",
+        "webserver": "hyper",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "Anansi [raw]",
+        "notes": "",
+        "versus": "None"
+      }
+    }
+  ]
+}

+ 19 - 0
frameworks/Rust/anansi/settings.toml

@@ -0,0 +1,19 @@
+secret_key = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+login_url = "/login"
+smtp_relay = ""
+smtp_username = ""
+smtp_password = ""
+
+[caches]
+
+[caches.default]
+location = "redis://127.0.0.1/"
+
+[databases]
+
+[databases.default]
+name = "hello_world"
+user = "benchmarkdbuser"
+password = "benchmarkdbpass"
+address = "tfb-database"
+max_conn = 512

+ 3 - 0
frameworks/Rust/anansi/src/hello/migrations/mod.rs

@@ -0,0 +1,3 @@
+use anansi::migrations::prelude::*;
+
+local_migrations! {}

+ 7 - 0
frameworks/Rust/anansi/src/hello/mod.rs

@@ -0,0 +1,7 @@
+pub mod urls;
+#[cfg(not(feature = "raw"))]
+pub mod records;
+pub mod migrations;
+
+pub const APP_NAME: &'static str = "hello";
+pub mod world;

+ 47 - 0
frameworks/Rust/anansi/src/hello/records.rs

@@ -0,0 +1,47 @@
+#![allow(non_snake_case)]
+use async_trait::async_trait;
+use anansi::web::{Result, BaseRequest};
+use anansi::record;
+use anansi::records::{Relate, Int, Text, random_int};
+use serde::Serialize;
+
+#[record(table_name = "World")]
+#[derive(Serialize)]
+pub struct World {
+    #[field(primary_key = "true", default_fn = "random_int")]
+    pub id: Int,
+    pub randomNumber: Int,
+}
+
+#[async_trait]
+impl<R: BaseRequest> Relate<R> for World {
+    async fn on_save(&self, _req: &R) -> Result<()> {
+        unimplemented!();
+    }
+    async fn on_delete(&self, _req: &R) -> Result<()> {
+        unimplemented!();
+    }
+}
+
+#[record(table_name = "Fortune")]
+pub struct Fortune {
+    #[field(primary_key = "true", default_fn = "random_int")]
+    pub id: Int,
+    pub message: Text,
+}
+
+impl Fortune {
+    pub fn additional() -> Self {
+        Self {id: Int::new(0), message: Text::from("Additional fortune added at request time.".to_string())}
+    }
+}
+
+#[async_trait]
+impl<R: BaseRequest> Relate<R> for Fortune {
+    async fn on_save(&self, _req: &R) -> Result<()> {
+        unimplemented!();
+    }
+    async fn on_delete(&self, _req: &R) -> Result<()> {
+        unimplemented!();
+    }
+}

+ 3 - 0
frameworks/Rust/anansi/src/hello/urls.rs

@@ -0,0 +1,3 @@
+use anansi::web::prelude::*;
+
+routes! {}

+ 5 - 0
frameworks/Rust/anansi/src/hello/world/mod.rs

@@ -0,0 +1,5 @@
+#[cfg(not(feature = "raw"))]
+pub mod views;
+#[cfg(feature = "raw")]
+pub mod raw;
+pub mod util;

+ 133 - 0
frameworks/Rust/anansi/src/hello/world/raw.rs

@@ -0,0 +1,133 @@
+use crate::prelude::*;
+use serde::Serialize;
+use anansi::check;
+use anansi::db::postgres::{PgDbRow, PgQuery};
+use super::util::get_query;
+use std::borrow::Cow;
+use anansi::db::DbRow;
+use rand::Rng;
+use std::fmt::Write;
+
+thread_local!(static UPDATES: Vec<Cow<'static, str>> = {
+    let mut updates = vec![Cow::from("")];
+    for num in 1..=500u16 {
+        let mut pl = 1;
+        let mut q = "UPDATE world SET randomnumber = CASE id ".to_string();
+        for _ in 1..=num {
+            let _ = write!(q, "WHEN ${} THEN ${} ", pl, pl + 1);
+            pl += 2;
+        }
+
+        q.push_str("ELSE randomnumber END WHERE id IN (");
+
+        for _ in 1..=num {
+            let _ = write!(q, "${},", pl);
+            pl += 1;
+        }
+
+        q.pop();
+        q.push(')');
+
+        updates.push(Cow::from(q));
+    }
+    updates
+});
+
+fn random_num() -> i32 {
+    rand::thread_rng().gen_range(1..=10_000)
+}
+
+#[derive(Copy, Clone, Serialize, Debug)]
+pub struct World {
+    id: i32,
+    randomnumber: i32,
+}
+
+#[derive(Serialize, Debug)]
+pub struct Fortune {
+    id: i32,
+    message: Cow<'static, str>,
+}
+
+#[base_view]
+fn base<R: Request>(_req: &mut R) -> Result<Response> {}
+
+#[viewer]
+impl<R: Request> WorldView<R> {
+    async fn get_world(req: &R) -> Result<PgDbRow> {
+        PgQuery::new("SELECT * FROM world WHERE id = $1")
+            .bind(random_num())
+            .fetch_one(req)
+            .await
+    }
+    async fn get_worlds(req: &R) -> Result<Vec<World>> {
+        let q = get_query(req.params());
+        let mut worlds = Vec::with_capacity(q as usize);
+        for _ in 0..q {
+            let row = Self::get_world(req).await?;
+            let world = World {
+                id: row.try_i32("id")?,
+                randomnumber: row.try_i32("randomnumber")?,
+            };
+            worlds.push(world);
+        }
+        Ok(worlds)
+    }
+    #[check(Site::is_visitor)]
+    pub async fn db(req: &mut R) -> Result<Response> {
+        let row = Self::get_world(req).await?;
+        let world = World {
+            id: row.try_i32("id")?,
+            randomnumber: row.try_i32("randomnumber")?,
+        };
+        Response::json(&world)
+    }
+    #[check(Site::is_visitor)]
+    pub async fn queries(req: &mut R) -> Result<Response> {
+        let worlds = Self::get_worlds(req).await?;
+        Response::json(&worlds)
+    }
+    #[view(Site::is_visitor)]
+    pub async fn raw_fortunes(req: &mut R) -> Result<Response> {
+        let title = "Fortunes";
+        let rows = PgQuery::new("SELECT * FROM fortune")
+            .fetch_all(req)
+            .await?;
+        let mut fortunes = vec![Fortune {
+            id: 0,
+            message: Cow::Borrowed("Additional fortune added at request time.")
+        }];
+        for row in rows {
+            fortunes.push(Fortune {
+                id: row.try_i32("id")?,
+                message: Cow::Owned(row.try_string("message")?),
+            })
+        }
+        fortunes.sort_by(|it, next| it.message.cmp(&next.message));
+    }
+    #[check(Site::is_visitor)]
+    pub async fn updates(req: &mut R) -> Result<Response> {
+        let q = get_query(req.params()) as usize;
+        let mut worlds = Vec::with_capacity(q);
+        let mut update = Cow::from("");
+        UPDATES.with(|u| {
+            update = u[q].clone();
+        });
+        let mut updates = PgQuery::new(&update);
+        for _ in 0..q {
+            let row = Self::get_world(req).await?;
+            let world = World {
+                id: row.try_i32("id")?,
+                randomnumber: random_num(),
+            };
+            updates = updates.bind(world.id)
+                .bind(world.randomnumber);
+            worlds.push(world);
+        }
+        for world in &worlds {
+            updates = updates.bind(world.id);
+        }
+        updates.execute(req).await?;
+        Response::json(&worlds)
+    }
+}

部分文件因为文件数量过多而无法显示