Browse Source

Merge branch 'master' of github.com:hggq/FrameworkBenchmarks

hzq 1 year ago
parent
commit
04f801f492
81 changed files with 1839 additions and 1021 deletions
  1. 7 7
      frameworks/C++/drogon/drogon-core.dockerfile
  2. 7 7
      frameworks/C++/drogon/drogon.dockerfile
  3. 2 2
      frameworks/C++/drogon/drogon_benchmark/controllers/FortuneCtrlRaw.cc
  4. 4 3
      frameworks/C++/drogon/drogon_benchmark/controllers/FortuneCtrlRaw.h
  5. 1 1
      frameworks/C++/drogon/drogon_benchmark/controllers/UpdatesCtrlRaw.cc
  6. 3 3
      frameworks/C/h2o/h2o.dockerfile
  7. 1 2
      frameworks/FSharp/giraffe/README.md
  8. 1 1
      frameworks/FSharp/giraffe/giraffe-newtonsoft.dockerfile
  9. 1 1
      frameworks/FSharp/giraffe/giraffe.dockerfile
  10. 4 4
      frameworks/FSharp/giraffe/src/App/App.fsproj
  11. 3 3
      frameworks/FSharp/zebra/src/App/App.fsproj
  12. 1 1
      frameworks/FSharp/zebra/zebra-simple.dockerfile
  13. 1 1
      frameworks/FSharp/zebra/zebra.dockerfile
  14. 14 22
      frameworks/Java/inverno/pom.xml
  15. 3 1
      frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/internal/SqlClientReactorScope.java
  16. 1 1
      frameworks/Java/light-java/pom.xml
  17. 9 0
      frameworks/Java/today/.gitignore
  18. 26 0
      frameworks/Java/today/README.md
  19. 30 0
      frameworks/Java/today/benchmark_config.json
  20. 63 0
      frameworks/Java/today/build.gradle
  21. 20 0
      frameworks/Java/today/config.toml
  22. 7 0
      frameworks/Java/today/gradle.properties
  23. 15 0
      frameworks/Java/today/settings.gradle
  24. 70 0
      frameworks/Java/today/src/main/java/cn/taketoday/benchmark/AppConfig.java
  25. 13 0
      frameworks/Java/today/src/main/java/cn/taketoday/benchmark/BenchmarkApplication.java
  26. 120 0
      frameworks/Java/today/src/main/java/cn/taketoday/benchmark/http/BenchmarkHttpHandler.java
  27. 54 0
      frameworks/Java/today/src/main/java/cn/taketoday/benchmark/model/Fortune.java
  28. 55 0
      frameworks/Java/today/src/main/java/cn/taketoday/benchmark/model/World.java
  29. 9 0
      frameworks/Java/today/src/main/resources/application-dev.yaml
  30. 14 0
      frameworks/Java/today/src/main/resources/application-test.yaml
  31. 41 0
      frameworks/Java/today/src/main/resources/application.yaml
  32. 21 0
      frameworks/Java/today/src/main/resources/templates/fortunes.ftl
  33. 11 0
      frameworks/Java/today/today.dockerfile
  34. 1 1
      frameworks/Java/undertow-jersey/pom.xml
  35. 1 1
      frameworks/Java/undertow/pom.xml
  36. 1 1
      frameworks/JavaScript/hapi/package.json
  37. 1 1
      frameworks/JavaScript/nodejs/package.json
  38. 2 1
      frameworks/PHP/php/php-h2o.dockerfile
  39. 2 2
      frameworks/Pascal/mormot/setup_and_build.sh
  40. 13 8
      frameworks/Pascal/mormot/src/raw.pas
  41. 1 1
      frameworks/Python/api_hour/requirements.txt
  42. 1 1
      frameworks/Python/blacksheep/requirements-gunicorn.txt
  43. 1 1
      frameworks/Python/heaven/requirements.txt
  44. 1 1
      frameworks/Python/panther/requirements.txt
  45. 3 1
      frameworks/Python/pyramid/requirements.txt
  46. 1 1
      frameworks/Python/quart/requirements-uvicorn.txt
  47. 1 1
      frameworks/Python/responder/requirements.txt
  48. 1 1
      frameworks/Python/routerling/requirements.txt
  49. 1 1
      frameworks/Python/uvicorn/requirements.txt
  50. 2 1
      frameworks/Ruby/h2o_mruby/h2o_mruby.dockerfile
  51. 175 173
      frameworks/Rust/ohkami/Cargo.lock
  52. 3 3
      frameworks/Rust/ohkami/Cargo.toml
  53. 5 5
      frameworks/Rust/ohkami/src/main.rs
  54. 4 3
      frameworks/Rust/ohkami/src/models.rs
  55. 5 4
      frameworks/Rust/ohkami/src/postgres.rs
  56. 10 7
      frameworks/Rust/ohkami/src/templates.rs
  57. 3 1
      frameworks/Rust/rocket/.gitignore
  58. 262 299
      frameworks/Rust/rocket/Cargo.lock
  59. 10 22
      frameworks/Rust/rocket/Cargo.toml
  60. 8 0
      frameworks/Rust/rocket/Rocket.toml
  61. 50 49
      frameworks/Rust/rocket/benchmark_config.json
  62. 1 1
      frameworks/Rust/rocket/rocket-diesel.dockerfile
  63. 1 7
      frameworks/Rust/rocket/rocket.dockerfile
  64. 0 2
      frameworks/Rust/rocket/rust-toolchain.toml
  65. 67 104
      frameworks/Rust/rocket/src/main.rs
  66. 3 5
      frameworks/Rust/rocket/src/models.rs
  67. 422 226
      frameworks/Rust/trillium/Cargo.lock
  68. 19 5
      frameworks/Rust/trillium/Cargo.toml
  69. 55 1
      frameworks/Rust/trillium/benchmark_config.json
  70. 14 1
      frameworks/Rust/trillium/src/main.rs
  71. 16 0
      frameworks/Rust/trillium/trillium-async-std.dockerfile
  72. 16 0
      frameworks/Rust/trillium/trillium-tokio.dockerfile
  73. 2 2
      frameworks/Rust/trillium/trillium.dockerfile
  74. 6 0
      frameworks/Ur/urweb/bench.ur
  75. 1 0
      frameworks/Ur/urweb/bench.urs
  76. 5 6
      frameworks/Ur/urweb/benchmark_config.json
  77. 2 2
      frameworks/Ur/urweb/config.toml
  78. 2 2
      frameworks/Ur/urweb/urweb-cache.dockerfile
  79. 2 2
      frameworks/Ur/urweb/urweb-mysql-cache.dockerfile
  80. 2 2
      frameworks/Ur/urweb/urweb-mysql.dockerfile
  81. 2 2
      frameworks/Ur/urweb/urweb.dockerfile

+ 7 - 7
frameworks/C++/drogon/drogon-core.dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:20.04
+FROM ubuntu:22.04
 
 
 COPY ./ ./
 COPY ./ ./
 
 
@@ -11,7 +11,7 @@ RUN  apt-get update -yqq && \
      zlib1g-dev && \
      zlib1g-dev && \
      add-apt-repository ppa:ubuntu-toolchain-r/test -y && \
      add-apt-repository ppa:ubuntu-toolchain-r/test -y && \
 	 apt-get update -yqq && \
 	 apt-get update -yqq && \
-	 apt-get install -yqq gcc-10 g++-10
+	 apt-get install -yqq gcc g++
 
 
 RUN locale-gen en_US.UTF-8
 RUN locale-gen en_US.UTF-8
 
 
@@ -19,10 +19,10 @@ ENV LANG en_US.UTF-8
 ENV LANGUAGE en_US:en
 ENV LANGUAGE en_US:en
 ENV LC_ALL en_US.UTF-8
 ENV LC_ALL en_US.UTF-8
 
 
-ENV CC=gcc-10
-ENV CXX=g++-10
-ENV AR=gcc-ar-10
-ENV RANLIB=gcc-ranlib-10
+ENV CC=gcc
+ENV CXX=g++
+ENV AR=gcc-ar
+ENV RANLIB=gcc-ranlib
 
 
 ENV IROOT=/install
 ENV IROOT=/install
 ENV DROGON_ROOT=$IROOT/drogon
 ENV DROGON_ROOT=$IROOT/drogon
@@ -41,7 +41,7 @@ RUN git clone https://github.com/an-tao/drogon
 
 
 WORKDIR $DROGON_ROOT
 WORKDIR $DROGON_ROOT
 
 
-RUN git checkout ebf87d69d7bb45dfa478ba364ef9374d9be25092
+RUN git checkout 96919df488e0ebaa0ed304bbd76bba33508df3cc 
 RUN git submodule update --init
 RUN git submodule update --init
 RUN mkdir build
 RUN mkdir build
 
 

+ 7 - 7
frameworks/C++/drogon/drogon.dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:20.04
+FROM ubuntu:22.04
 
 
 COPY ./ ./
 COPY ./ ./
 
 
@@ -11,7 +11,7 @@ RUN  apt-get update -yqq && \
      zlib1g-dev && \
      zlib1g-dev && \
      add-apt-repository ppa:ubuntu-toolchain-r/test -y && \
      add-apt-repository ppa:ubuntu-toolchain-r/test -y && \
 	 apt-get update -yqq && \
 	 apt-get update -yqq && \
-	 apt-get install -yqq gcc-10 g++-10
+	 apt-get install -yqq gcc g++
 
 
 RUN locale-gen en_US.UTF-8
 RUN locale-gen en_US.UTF-8
 
 
@@ -19,10 +19,10 @@ ENV LANG en_US.UTF-8
 ENV LANGUAGE en_US:en
 ENV LANGUAGE en_US:en
 ENV LC_ALL en_US.UTF-8
 ENV LC_ALL en_US.UTF-8
 
 
-ENV CC=gcc-10
-ENV CXX=g++-10
-ENV AR=gcc-ar-10
-ENV RANLIB=gcc-ranlib-10
+ENV CC=gcc
+ENV CXX=g++
+ENV AR=gcc-ar
+ENV RANLIB=gcc-ranlib
 
 
 ENV IROOT=/install
 ENV IROOT=/install
 ENV DROGON_ROOT=$IROOT/drogon
 ENV DROGON_ROOT=$IROOT/drogon
@@ -41,7 +41,7 @@ RUN git clone https://github.com/an-tao/drogon
 
 
 WORKDIR $DROGON_ROOT
 WORKDIR $DROGON_ROOT
 
 
-RUN git checkout ebf87d69d7bb45dfa478ba364ef9374d9be25092
+RUN git checkout 96919df488e0ebaa0ed304bbd76bba33508df3cc 
 RUN git submodule update --init
 RUN git submodule update --init
 RUN mkdir build
 RUN mkdir build
 
 

+ 2 - 2
frameworks/C++/drogon/drogon_benchmark/controllers/FortuneCtrlRaw.cc

@@ -22,8 +22,8 @@ void FortuneCtrlRaw::asyncHandleHttpRequest(
         rows.reserve(r.size() + 1);
         rows.reserve(r.size() + 1);
         for (auto const &row : r)
         for (auto const &row : r)
         {
         {
-            rows.emplace_back(row[0ul].as<string_view>(),   // id
-                              row[1ul].as<string_view>());  // message
+            rows.emplace_back(row[0ul].as<std::string_view>(),   // id
+                              row[1ul].as<std::string_view>());  // message
         }
         }
         rows.emplace_back("0", "Additional fortune added at request time.");
         rows.emplace_back("0", "Additional fortune added at request time.");
         std::sort(rows.begin(),
         std::sort(rows.begin(),

+ 4 - 3
frameworks/C++/drogon/drogon_benchmark/controllers/FortuneCtrlRaw.h

@@ -1,17 +1,18 @@
 #pragma once
 #pragma once
 #include <drogon/HttpSimpleController.h>
 #include <drogon/HttpSimpleController.h>
 #include <drogon/IOThreadStorage.h>
 #include <drogon/IOThreadStorage.h>
+#include <string_view>
 
 
 using namespace drogon;
 using namespace drogon;
 struct Fortune
 struct Fortune
 {
 {
-    Fortune(string_view &&id, string_view &&message)
+    Fortune(std::string_view &&id, std::string_view &&message)
         : id_(std::move(id)), message_(std::move(message))
         : id_(std::move(id)), message_(std::move(message))
     {
     {
     }
     }
     Fortune() = default;
     Fortune() = default;
-    string_view id_;
-    string_view message_;
+    std::string_view id_;
+    std::string_view message_;
 };
 };
 class FortuneCtrlRaw : public drogon::HttpSimpleController<FortuneCtrlRaw>
 class FortuneCtrlRaw : public drogon::HttpSimpleController<FortuneCtrlRaw>
 {
 {

+ 1 - 1
frameworks/C++/drogon/drogon_benchmark/controllers/UpdatesCtrlRaw.cc

@@ -43,7 +43,7 @@ void UpdatesCtrlRaw::update(
     const DbClientPtr &client)
     const DbClientPtr &client)
 {
 {
     auto const &sql = getSQL(results->size());
     auto const &sql = getSQL(results->size());
-    auto sqlBinder = *client << string_view(sql.data(), sql.length());
+    auto sqlBinder = *client << std::string_view(sql.data(), sql.length());
     Json::Value json;
     Json::Value json;
     json.resize(0);
     json.resize(0);
     for (auto const &w : *results)
     for (auto const &w : *results)

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

@@ -1,4 +1,4 @@
-ARG UBUNTU_VERSION=22.04
+ARG UBUNTU_VERSION=24.04
 
 
 ARG H2O_APP_PREFIX=/opt/h2o_app
 ARG H2O_APP_PREFIX=/opt/h2o_app
 
 
@@ -25,6 +25,7 @@ RUN apt-get -yqq update && \
       libwslay-dev \
       libwslay-dev \
       libyajl-dev \
       libyajl-dev \
       libz-dev \
       libz-dev \
+      llvm-dev \
       make \
       make \
       ninja-build \
       ninja-build \
       pkg-config \
       pkg-config \
@@ -46,8 +47,7 @@ RUN curl -LSs "https://github.com/h2o/h2o/archive/${H2O_VERSION}.tar.gz" | \
       -G Ninja \
       -G Ninja \
       -S . && \
       -S . && \
     cmake --build build -j && \
     cmake --build build -j && \
-    cmake --install build && \
-    cp -a deps/picotls/include/picotls* deps/quicly/include/quicly* /usr/local/include
+    cmake --install build
 
 
 ARG MUSTACHE_C_REVISION=7fe52392879d0188c172d94bb4fde7c513d6b929
 ARG MUSTACHE_C_REVISION=7fe52392879d0188c172d94bb4fde7c513d6b929
 
 

+ 1 - 2
frameworks/FSharp/giraffe/README.md

@@ -1,9 +1,8 @@
 # Giraffe Benchmarks on Linux
 # Giraffe Benchmarks on Linux
 
 
-This application tests Giraffe in 3 modes:
+This application tests Giraffe in 2 modes:
 
 
 - Default: Using Giraffe's Endpoint Routing APIs with the `System.Text.Json` serializer
 - Default: Using Giraffe's Endpoint Routing APIs with the `System.Text.Json` serializer
-- Utf8Json: Testing the JSON endpoint with the `Utf8Json` serializer
 - Newtonsoft: Testing the JSON endpoint with the `NewtonsoftJson` serializer
 - Newtonsoft: Testing the JSON endpoint with the `NewtonsoftJson` serializer
 
 
 ## Infrastructure Software Versions
 ## Infrastructure Software Versions

+ 1 - 1
frameworks/FSharp/giraffe/giraffe-newtonsoft.dockerfile

@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/dotnet/sdk:8.0.100 AS build
+FROM mcr.microsoft.com/dotnet/sdk:8.0.204 AS build
 WORKDIR /app
 WORKDIR /app
 COPY src/App .
 COPY src/App .
 RUN dotnet publish -c Release -o out
 RUN dotnet publish -c Release -o out

+ 1 - 1
frameworks/FSharp/giraffe/giraffe.dockerfile

@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/dotnet/sdk:8.0.100 AS build
+FROM mcr.microsoft.com/dotnet/sdk:8.0.204 AS build
 WORKDIR /app
 WORKDIR /app
 COPY src/App .
 COPY src/App .
 RUN dotnet publish -c Release -o out
 RUN dotnet publish -c Release -o out

+ 4 - 4
frameworks/FSharp/giraffe/src/App/App.fsproj

@@ -6,10 +6,10 @@
   </PropertyGroup>
   </PropertyGroup>
 
 
   <ItemGroup>
   <ItemGroup>
-    <PackageReference Update="FSharp.Core" Version="8.0.100" />
-    <PackageReference Include="Dapper" Version="2.1.21" />
-    <PackageReference Include="Giraffe" Version="6.2.0" />
-    <PackageReference Include="Npgsql" Version="8.0.0-rc.2" />
+    <PackageReference Update="FSharp.Core" Version="8.0.200" />
+    <PackageReference Include="Dapper" Version="2.1.44" />
+    <PackageReference Include="Giraffe" Version="6.4.0" />
+    <PackageReference Include="Npgsql" Version="8.0.2" />
   </ItemGroup>
   </ItemGroup>
 
 
   <ItemGroup>
   <ItemGroup>

+ 3 - 3
frameworks/FSharp/zebra/src/App/App.fsproj

@@ -9,10 +9,10 @@
   </PropertyGroup>
   </PropertyGroup>
 
 
   <ItemGroup>
   <ItemGroup>
-    <PackageReference Include="Dapper" Version="2.1.21" />
-    <PackageReference Include="Npgsql" Version="8.0.0-rc.2" />
+    <PackageReference Include="Dapper" Version="2.1.44" />
+    <PackageReference Include="Npgsql" Version="8.0.2" />
     <PackageReference Include="Utf8Json" Version="1.3.7" />
     <PackageReference Include="Utf8Json" Version="1.3.7" />
-    <PackageReference Update="FSharp.Core" Version="8.0.100" />
+    <PackageReference Update="FSharp.Core" Version="8.0.200" />
   </ItemGroup>
   </ItemGroup>
 
 
   <ItemGroup>
   <ItemGroup>

+ 1 - 1
frameworks/FSharp/zebra/zebra-simple.dockerfile

@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/dotnet/sdk:8.0.100 AS build
+FROM mcr.microsoft.com/dotnet/sdk:8.0.204 AS build
 WORKDIR /app
 WORKDIR /app
 COPY src/App .
 COPY src/App .
 RUN dotnet publish -c Release -o out
 RUN dotnet publish -c Release -o out

+ 1 - 1
frameworks/FSharp/zebra/zebra.dockerfile

@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/dotnet/sdk:8.0.100 AS build
+FROM mcr.microsoft.com/dotnet/sdk:8.0.204 AS build
 WORKDIR /app
 WORKDIR /app
 COPY src/App .
 COPY src/App .
 RUN dotnet publish -c Release -o out
 RUN dotnet publish -c Release -o out

+ 14 - 22
frameworks/Java/inverno/pom.xml

@@ -6,7 +6,7 @@
 	<parent>
 	<parent>
 		<groupId>io.inverno.dist</groupId>
 		<groupId>io.inverno.dist</groupId>
 		<artifactId>inverno-parent</artifactId>
 		<artifactId>inverno-parent</artifactId>
-		<version>1.7.0</version>
+		<version>1.9.0</version>
 	</parent>
 	</parent>
 	<groupId>com.techempower</groupId>
 	<groupId>com.techempower</groupId>
 	<artifactId>inverno-benchmark</artifactId>
 	<artifactId>inverno-benchmark</artifactId>
@@ -71,31 +71,12 @@
 		<dependency>
 		<dependency>
 			<groupId>io.netty</groupId>
 			<groupId>io.netty</groupId>
 			<artifactId>netty-handler-proxy</artifactId>
 			<artifactId>netty-handler-proxy</artifactId>
-			<version>${version.netty}</version>
 		</dependency>
 		</dependency>
 		<dependency>
 		<dependency>
 			<groupId>io.netty</groupId>
 			<groupId>io.netty</groupId>
 			<artifactId>netty-resolver-dns</artifactId>
 			<artifactId>netty-resolver-dns</artifactId>
-			<version>${version.netty}</version>
 		</dependency>
 		</dependency>
 
 
-		<!--<dependency>
-			<groupId>io.netty</groupId>
-			<artifactId>netty-transport-native-epoll</artifactId>
-			<classifier>linux-x86_64</classifier>
-		</dependency>-->
-		
-		<dependency>
-			<groupId>io.netty.incubator</groupId>
-			<artifactId>netty-incubator-transport-native-io_uring</artifactId>
-			<classifier>linux-x86_64</classifier>
-		</dependency>
-		
-		<dependency>
-			<groupId>io.vertx</groupId>
-			<artifactId>vertx-io_uring-incubator</artifactId>
-		</dependency>
-		
 		<dependency>
 		<dependency>
 			<groupId>org.apache.logging.log4j</groupId>
 			<groupId>org.apache.logging.log4j</groupId>
 			<artifactId>log4j-core</artifactId>
 			<artifactId>log4j-core</artifactId>
@@ -138,6 +119,9 @@
 								</configuration>
 								</configuration>
 							</execution>
 							</execution>
 						</executions>
 						</executions>
+						<configuration>
+							<vmOptions>--add-modules io.netty.transport.unix.common,io.netty.transport.classes.epoll,io.netty.transport.epoll.linux.x86_64</vmOptions>
+						</configuration>
 					</plugin>
 					</plugin>
 				</plugins>
 				</plugins>
 			</build>
 			</build>
@@ -146,10 +130,15 @@
 			<id>io.inverno.io_uring</id>
 			<id>io.inverno.io_uring</id>
 			<dependencies>
 			<dependencies>
 				<dependency>
 				<dependency>
-					<groupId>io.netty</groupId>
-					<artifactId>netty-transport-native-epoll</artifactId>
+					<groupId>io.netty.incubator</groupId>
+					<artifactId>netty-incubator-transport-native-io_uring</artifactId>
 					<classifier>linux-x86_64</classifier>
 					<classifier>linux-x86_64</classifier>
 				</dependency>
 				</dependency>
+		
+				<dependency>
+					<groupId>io.vertx</groupId>
+					<artifactId>vertx-io_uring-incubator</artifactId>
+				</dependency>
 			</dependencies>
 			</dependencies>
 			<build>
 			<build>
 				<plugins>
 				<plugins>
@@ -177,6 +166,9 @@
 								</configuration>
 								</configuration>
 							</execution>
 							</execution>
 						</executions>
 						</executions>
+						<configuration>
+							<vmOptions>--add-modules io.netty.transport.unix.common,io.netty.incubator.transport.classes.io_uring,io.netty.incubator.transport.io_uring.linux.x86_64</vmOptions>
+						</configuration>
 					</plugin>
 					</plugin>
 				</plugins>
 				</plugins>
 			</build>
 			</build>

+ 3 - 1
frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/internal/SqlClientReactorScope.java

@@ -59,6 +59,8 @@ public class SqlClientReactorScope extends ReactorScope<Mono<SqlClient>> {
 	
 	
 	@Override
 	@Override
 	protected Mono<SqlClient> create() {
 	protected Mono<SqlClient> create() {
-		return Mono.fromCompletionStage(PgConnection.connect(this.vertx, this.connectOptions).toCompletionStage()).map(pgConn -> (SqlClient)new ConnectionSqlClient(pgConn)).cache();
+		return Mono.fromCompletionStage(() -> PgConnection.connect(this.vertx, this.connectOptions).toCompletionStage())
+			.map(pgConn -> (SqlClient)new ConnectionSqlClient(pgConn))
+			.cacheInvalidateWhen(client -> ((ConnectionSqlClient)client).onClose());
 	}
 	}
 }
 }

+ 1 - 1
frameworks/Java/light-java/pom.xml

@@ -25,7 +25,7 @@
         <maven.compiler.target>11</maven.compiler.target>
         <maven.compiler.target>11</maven.compiler.target>
         <version.light-4j>2.0.1</version.light-4j>
         <version.light-4j>2.0.1</version.light-4j>
         <version.logback>1.3.12</version.logback>
         <version.logback>1.3.12</version.logback>
-        <version.undertow>2.3.5.Final</version.undertow>
+        <version.undertow>2.3.12.Final</version.undertow>
         <version.hikaricp>3.3.1</version.hikaricp>
         <version.hikaricp>3.3.1</version.hikaricp>
         <version.mysql>8.0.28</version.mysql>
         <version.mysql>8.0.28</version.mysql>
         <version.postgres>42.7.2</version.postgres>
         <version.postgres>42.7.2</version.postgres>

+ 9 - 0
frameworks/Java/today/.gitignore

@@ -0,0 +1,9 @@
+# Ignore Gradle project-specific cache directory
+.gradle
+
+# Ignore Gradle build output directory
+build
+
+.idea
+today.properties
+gradle

+ 26 - 0
frameworks/Java/today/README.md

@@ -0,0 +1,26 @@
+# [TODAY Infrastructure](https://github.com/TAKETODAY/today-infrastructure) Benchmarking Test
+
+## Test URLs
+### JSON
+
+http://localhost:8080/json
+
+### PLAINTEXT
+
+http://localhost:8080/plaintext
+
+### DB
+
+http://localhost:8080/db
+
+### QUERY
+
+http://localhost:8080/queries?queries=
+
+### UPDATE
+
+http://localhost:8080/update?queries=
+
+### FORTUNES
+
+http://localhost:8080/fortunes

+ 30 - 0
frameworks/Java/today/benchmark_config.json

@@ -0,0 +1,30 @@
+{
+  "framework": "today",
+  "tests": [
+    {
+      "default": {
+        "json_url": "/json",
+        "plaintext_url": "/plaintext",
+        "db_url": "/db",
+        "query_url": "/queries?queries=",
+        "fortune_url": "/fortunes",
+        "update_url": "/updates?queries=",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Fullstack",
+        "database": "mysql",
+        "framework": "Today",
+        "language": "Java",
+        "flavor": "None",
+        "orm": "micro",
+        "platform": "Netty",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "Today",
+        "notes": "",
+        "versus": "None"
+      }
+    }
+  ]
+}

+ 63 - 0
frameworks/Java/today/build.gradle

@@ -0,0 +1,63 @@
+description = "benchmark"
+
+apply plugin: "java"
+apply plugin: "application"
+apply plugin: 'cn.taketoday.application'
+apply plugin: 'io.spring.dependency-management'
+
+configure(allprojects) {
+  group = "cn.taketoday.benchmark"
+
+  repositories {
+    mavenCentral()
+    maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
+  }
+}
+
+dependencies {
+  implementation 'cn.taketoday:today-starter-netty'
+  implementation 'cn.taketoday:today-starter-json'
+  implementation 'cn.taketoday:today-starter-jdbc'
+  implementation 'cn.taketoday:today-starter-web'
+  implementation 'cn.taketoday:today-starter-freemarker'
+
+  implementation 'mysql:mysql-connector-java'
+
+  implementation 'ch.qos.logback:logback-classic'
+
+  implementation('io.netty:netty-transport-native-epoll') {
+    artifact {
+      classifier = 'linux-x86_64'
+    }
+  }
+
+//  implementation('io.netty:netty-transport-native-kqueue') {
+//    artifact {
+//      classifier = 'osx-aarch_64'
+//    }
+//  }
+
+}
+
+java {
+  sourceCompatibility = JavaVersion.VERSION_17
+  targetCompatibility = JavaVersion.VERSION_17
+}
+
+application {
+  mainClass = 'cn.taketoday.benchmark.BenchmarkApplication'
+  applicationDefaultJvmArgs = [
+      "-server",
+      "-XX:+UseNUMA",
+      "-XX:+UseG1GC",
+      "-XX:+DisableExplicitGC",
+      "-XX:-StackTraceInThrowable",
+      "-XX:+UseStringDeduplication",
+      "-Dinfra.profiles.active=test",
+      "-Dio.netty.buffer.checkBounds=false",
+      "-Dio.netty.buffer.checkAccessible=false",
+      "-Dio.netty.leakDetection.level=disabled",
+      "--add-opens=java.base/java.nio=ALL-UNNAMED",
+      "--add-opens=java.base/sun.nio.ch=ALL-UNNAMED"
+  ]
+}

+ 20 - 0
frameworks/Java/today/config.toml

@@ -0,0 +1,20 @@
+[framework]
+name = "today"
+
+[main]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+urls.db = "/db"
+urls.query = "/queries?queries="
+urls.update = "/updates?queries="
+urls.fortune = "/fortunes"
+approach = "Realistic"
+classification = "Fullstack"
+database = "mysql"
+database_os = "Linux"
+display_name = "today"
+os = "Linux"
+orm = "raw"
+platform = "Netty"
+webserver = "None"
+versus = "None"

+ 7 - 0
frameworks/Java/today/gradle.properties

@@ -0,0 +1,7 @@
+version=1.0.0
+#infraVersion=4.0.0-Draft.6-SNAPSHOT
+infraVersion=4.0.0-Draft.6
+
+org.gradle.caching=true
+org.gradle.jvmargs=-Xmx2048m
+org.gradle.parallel=true

+ 15 - 0
frameworks/Java/today/settings.gradle

@@ -0,0 +1,15 @@
+buildscript {
+  repositories {
+    mavenLocal()
+    maven {
+      url "https://oss.sonatype.org/content/repositories/snapshots/"
+    }
+    mavenCentral()
+  }
+
+  dependencies {
+    classpath "cn.taketoday:infra-gradle-plugin:$infraVersion"
+  }
+}
+
+rootProject.name = 'today'

+ 70 - 0
frameworks/Java/today/src/main/java/cn/taketoday/benchmark/AppConfig.java

@@ -0,0 +1,70 @@
+package cn.taketoday.benchmark;
+
+import java.time.ZonedDateTime;
+
+import javax.sql.DataSource;
+
+import cn.taketoday.beans.factory.annotation.DisableAllDependencyInjection;
+import cn.taketoday.beans.factory.config.BeanDefinition;
+import cn.taketoday.context.annotation.Configuration;
+import cn.taketoday.context.annotation.Role;
+import cn.taketoday.framework.web.netty.NettyRequestConfig;
+import cn.taketoday.framework.web.netty.SendErrorHandler;
+import cn.taketoday.jdbc.RepositoryManager;
+import cn.taketoday.jdbc.persistence.EntityManager;
+import cn.taketoday.stereotype.Component;
+import io.netty.handler.codec.http.DefaultHttpHeadersFactory;
+import io.netty.handler.codec.http.HttpHeaders;
+import io.netty.handler.codec.http.HttpHeadersFactory;
+import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
+
+import static cn.taketoday.http.HttpHeaders.DATE_FORMATTER;
+
+/**
+ * @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
+ * @since 1.0 2024/3/19 12:59
+ */
+@DisableAllDependencyInjection
+@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
+@Configuration(proxyBeanMethods = false)
+class AppConfig {
+
+  private static final DefaultHttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory();
+
+  @Component
+  static RepositoryManager repositoryManager(DataSource dataSource) {
+    return new RepositoryManager(dataSource);
+  }
+
+  @Component
+  static EntityManager entityManager(RepositoryManager repositoryManager) {
+    return repositoryManager.getEntityManager();
+  }
+
+  @Component
+  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
+  static NettyRequestConfig nettyRequestConfig(SendErrorHandler sendErrorHandler) {
+    var factory = new DefaultHttpDataFactory(false);
+    return NettyRequestConfig.forBuilder()
+            .httpDataFactory(factory)
+            .sendErrorHandler(sendErrorHandler)
+            .headersFactory(new HttpHeadersFactory() {
+
+              @Override
+              public HttpHeaders newHeaders() {
+                HttpHeaders headers = headersFactory.newHeaders();
+                headers.set("Server", "TODAY");
+                headers.set("Date", DATE_FORMATTER.format(ZonedDateTime.now()));
+                return headers;
+              }
+
+              @Override
+              public HttpHeaders newEmptyHeaders() {
+                return headersFactory.newEmptyHeaders();
+              }
+            })
+            .secure(false)
+            .build();
+  }
+
+}

+ 13 - 0
frameworks/Java/today/src/main/java/cn/taketoday/benchmark/BenchmarkApplication.java

@@ -0,0 +1,13 @@
+package cn.taketoday.benchmark;
+
+import cn.taketoday.framework.Application;
+import cn.taketoday.framework.InfraApplication;
+
+@InfraApplication
+public class BenchmarkApplication {
+
+  public static void main(String[] args) {
+    Application.run(BenchmarkApplication.class, args);
+  }
+
+}

+ 120 - 0
frameworks/Java/today/src/main/java/cn/taketoday/benchmark/http/BenchmarkHttpHandler.java

@@ -0,0 +1,120 @@
+package cn.taketoday.benchmark.http;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.stream.IntStream;
+
+import cn.taketoday.benchmark.model.Fortune;
+import cn.taketoday.benchmark.model.World;
+import cn.taketoday.http.MediaType;
+import cn.taketoday.http.ResponseEntity;
+import cn.taketoday.jdbc.persistence.EntityManager;
+import cn.taketoday.lang.Nullable;
+import cn.taketoday.ui.Model;
+import cn.taketoday.web.annotation.GET;
+import cn.taketoday.web.annotation.RestController;
+import cn.taketoday.web.view.ViewRef;
+
+/**
+ * @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
+ * @since 1.0 2024/3/19 12:56
+ */
+@RestController
+final class BenchmarkHttpHandler {
+
+  private static final int MIN_WORLD_NUMBER = 1;
+  private static final int MAX_WORLD_NUMBER = 10_000;
+
+  private final EntityManager entityManager;
+
+  BenchmarkHttpHandler(EntityManager entityManager) {
+    this.entityManager = entityManager;
+  }
+
+  @GET("/json")
+  public ResponseEntity<Map<String, String>> json() {
+    return ResponseEntity.ok()
+            .contentType(MediaType.APPLICATION_JSON)
+            .body(Map.of("message", "Hello, World!"));
+  }
+
+  @GET("/plaintext")
+  public String plaintext() {
+    return "Hello, World!";
+  }
+
+  @GET("/db")
+  public World db() {
+    return entityManager.findById(World.class, nextInt());
+  }
+
+  @GET("/queries")
+  public List<World> queries(@Nullable String queries) {
+    return randomNumbers()
+            .mapToObj(this::findWorldById)
+            .limit(parseQueryCount(queries))
+            .toList();
+  }
+
+  @GET("/updates")
+  public List<World> updates(@Nullable String queries) {
+    return randomNumbers()
+            .mapToObj(this::findWorldById)
+            .filter(Objects::nonNull)
+            .peek(world -> {
+              world.setRandomNumber(nextInt());
+              entityManager.updateById(world);
+            })
+            .limit(parseQueryCount(queries))
+            .toList();
+  }
+
+  @GET("/fortunes")
+  public ViewRef fortunes(Model model) {
+    List<Fortune> fortunes = entityManager.find(Fortune.class);
+    fortunes.add(new Fortune(0, "Additional fortune added at request time."));
+    fortunes.sort(Comparator.comparing(Fortune::getMessage));
+
+    model.addAttribute("fortunes", fortunes);
+    return ViewRef.forViewName("fortunes");
+  }
+
+  @Nullable
+  private World findWorldById(int id) {
+    return entityManager.findById(World.class, boxed[id]);
+  }
+
+  //
+
+  private static IntStream randomNumbers() {
+    return ThreadLocalRandom.current()
+            .ints(MIN_WORLD_NUMBER, MAX_WORLD_NUMBER)
+            .distinct();
+  }
+
+  private static final Integer[] boxed = IntStream.range(MIN_WORLD_NUMBER, MAX_WORLD_NUMBER + 1)
+          .boxed()
+          .toArray(Integer[]::new);
+
+  private static Integer nextInt() {
+    return boxed[ThreadLocalRandom.current().nextInt(MIN_WORLD_NUMBER, MAX_WORLD_NUMBER)];
+  }
+
+  private static int parseQueryCount(@Nullable String textValue) {
+    if (textValue == null) {
+      return 1;
+    }
+    int parsedValue;
+    try {
+      parsedValue = Integer.parseInt(textValue);
+    }
+    catch (NumberFormatException e) {
+      return 1;
+    }
+    return Math.min(500, Math.max(1, parsedValue));
+  }
+
+}

+ 54 - 0
frameworks/Java/today/src/main/java/cn/taketoday/benchmark/model/Fortune.java

@@ -0,0 +1,54 @@
+package cn.taketoday.benchmark.model;
+
+import java.util.Objects;
+
+import cn.taketoday.jdbc.persistence.Id;
+import cn.taketoday.jdbc.persistence.Table;
+
+@Table("fortune")
+public class Fortune {
+
+  @Id
+  private Integer id;
+
+  private String message;
+
+  public Fortune() { }
+
+  public Fortune(Integer id, String message) {
+    this.id = id;
+    this.message = message;
+  }
+
+  public void setId(Integer id) {
+    this.id = id;
+  }
+
+  public void setMessage(String message) {
+    this.message = message;
+  }
+
+  public Integer getId() {
+    return id;
+  }
+
+  public String getMessage() {
+    return message;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o)
+      return true;
+    if (!(o instanceof Fortune fortune))
+      return false;
+    return Objects.equals(id, fortune.id)
+            && Objects.equals(message, fortune.message);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(id, message);
+  }
+
+}

+ 55 - 0
frameworks/Java/today/src/main/java/cn/taketoday/benchmark/model/World.java

@@ -0,0 +1,55 @@
+package cn.taketoday.benchmark.model;
+
+import java.util.Objects;
+
+import cn.taketoday.jdbc.persistence.Column;
+import cn.taketoday.jdbc.persistence.Id;
+import cn.taketoday.jdbc.persistence.Table;
+
+@Table("world")
+public class World {
+
+  @Id
+  private Integer id;
+
+  @Column("randomNumber")
+  private Integer randomNumber;
+
+  public World() { }
+
+  public World(Integer id, Integer randomNumber) {
+    this.id = id;
+    this.randomNumber = randomNumber;
+  }
+
+  public Integer getId() {
+    return id;
+  }
+
+  public Integer getRandomNumber() {
+    return randomNumber;
+  }
+
+  public void setId(Integer id) {
+    this.id = id;
+  }
+
+  public void setRandomNumber(Integer randomNumber) {
+    this.randomNumber = randomNumber;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o)
+      return true;
+    if (!(o instanceof World world))
+      return false;
+    return Objects.equals(id, world.id)
+            && Objects.equals(randomNumber, world.randomNumber);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(id, randomNumber);
+  }
+}

+ 9 - 0
frameworks/Java/today/src/main/resources/application-dev.yaml

@@ -0,0 +1,9 @@
+datasource:
+  url: jdbc:mysql://localhost:3306/hello_world?useUnicode=true&characterEncoding=utf8&useSSL=false&autoReconnect=true&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
+  username: root
+  password: 88888888
+
+logging:
+  level:
+    root: info
+    sql: debug

+ 14 - 0
frameworks/Java/today/src/main/resources/application-test.yaml

@@ -0,0 +1,14 @@
+datasource:
+  url: jdbc:mysql://tfb-database:3306/hello_world?useUnicode=true&characterEncoding=utf8&useSSL=false&autoReconnect=true&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
+  username: benchmarkdbuser
+  password: benchmarkdbpass
+
+logging:
+  level:
+    root: info
+
+server:
+  netty:
+    acceptor-threads: 4
+    worker-threads: 8
+    max-connection: 65535

+ 41 - 0
frameworks/Java/today/src/main/resources/application.yaml

@@ -0,0 +1,41 @@
+app:
+  name: benchmark-app
+
+server:
+  port: 8080
+
+infra:
+  output:
+    ansi:
+      enabled: always
+
+freemarker:
+  cache: true
+  settings:
+    classic_compatible: true
+    date_format: yyyy-MM-dd
+    datetime_format: yyyy-MM-dd HH:mm:ss
+    default_encoding: UTF-8
+    locale: UTF-8
+    log_template_exceptions: false
+    number_format: 0.####
+    tag_syntax: auto_detect
+    template_exception_handler: ignore
+    template_update_delay: 0
+    time_format: HH:mm:ss
+    url_escaping_charset: UTF-8
+
+datasource:
+  name: 'app-datasource'
+  type: com.zaxxer.hikari.HikariDataSource
+  driver-class-name: com.mysql.cj.jdbc.Driver
+  hikari:
+    maximum-pool-size: 20
+    max-lifetime: 120000
+    connection-test-query: 'select 1'
+
+logging:
+  level:
+    root: OFF
+  pattern:
+    dateformat: 'yyyy-MM-dd HH:mm:ss.SSS'

+ 21 - 0
frameworks/Java/today/src/main/resources/templates/fortunes.ftl

@@ -0,0 +1,21 @@
+<#-- @ftlvariable name="fortunes" type="cn.taketoday.benchmark.model.Fortune[]" -->
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Fortunes</title>
+</head>
+<body>
+<table>
+  <tr>
+    <th>id</th>
+    <th>message</th>
+  </tr>
+    <#list fortunes as fortune>
+      <tr>
+        <td>#{fortune.id}</td>
+        <td>${fortune.message?html}</td>
+      </tr>
+    </#list>
+</table>
+</body>
+</html>

+ 11 - 0
frameworks/Java/today/today.dockerfile

@@ -0,0 +1,11 @@
+FROM gradle:8.6.0-jdk17 as build
+COPY --chown=gradle:gradle . /home/gradle/src
+WORKDIR /home/gradle/src
+RUN gradle installInfraDist --no-daemon
+
+FROM openjdk:21
+WORKDIR /today
+COPY --from=build /home/gradle/src/build/install/today-infra-app/ ./
+
+EXPOSE 8080
+ENTRYPOINT "./bin/today"

+ 1 - 1
frameworks/Java/undertow-jersey/pom.xml

@@ -174,7 +174,7 @@
     <dependency>
     <dependency>
       <groupId>io.undertow</groupId>
       <groupId>io.undertow</groupId>
       <artifactId>undertow-core</artifactId>
       <artifactId>undertow-core</artifactId>
-      <version>2.3.5.Final</version>
+      <version>2.3.12.Final</version>
     </dependency>
     </dependency>
 
 
     <dependency>
     <dependency>

+ 1 - 1
frameworks/Java/undertow/pom.xml

@@ -20,7 +20,7 @@
     <maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
     <maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
     <mustache.version>0.9.10</mustache.version>
     <mustache.version>0.9.10</mustache.version>
     <postgresql.version>42.7.2</postgresql.version>
     <postgresql.version>42.7.2</postgresql.version>
-    <undertow.version>2.3.5.Final</undertow.version>
+    <undertow.version>2.3.12.Final</undertow.version>
   </properties>
   </properties>
 
 
   <dependencies>
   <dependencies>

+ 1 - 1
frameworks/JavaScript/hapi/package.json

@@ -10,7 +10,7 @@
     "handlebars": "4.3.0",
     "handlebars": "4.3.0",
     "mongoose": "5.13.20",
     "mongoose": "5.13.20",
     "mysql": "2.16.0",
     "mysql": "2.16.0",
-    "mysql2": "1.6.5",
+    "mysql2": "3.9.4",
     "pg": "8.5.1",
     "pg": "8.5.1",
     "pg-hstore": "2.3.2",
     "pg-hstore": "2.3.2",
     "sequelize": "6.29.0"
     "sequelize": "6.29.0"

+ 1 - 1
frameworks/JavaScript/nodejs/package.json

@@ -8,7 +8,7 @@
     "mongodb": "3.7.3",
     "mongodb": "3.7.3",
     "mongoose": "5.13.20",
     "mongoose": "5.13.20",
     "mysql": "2.16.0",
     "mysql": "2.16.0",
-    "mysql2": "1.6.5",
+    "mysql2": "3.9.4",
     "parseurl": "1.3.2",
     "parseurl": "1.3.2",
     "pg": "8.5.0",
     "pg": "8.5.0",
     "pg-hstore": "2.3.2",
     "pg-hstore": "2.3.2",

+ 2 - 1
frameworks/PHP/php/php-h2o.dockerfile

@@ -1,4 +1,4 @@
-ARG UBUNTU_VERSION=22.04
+ARG UBUNTU_VERSION=24.04
 
 
 ARG H2O_PREFIX=/opt/h2o
 ARG H2O_PREFIX=/opt/h2o
 
 
@@ -22,6 +22,7 @@ RUN apt-get -yqq update && \
       libuv1-dev \
       libuv1-dev \
       libwslay-dev \
       libwslay-dev \
       libz-dev \
       libz-dev \
+      llvm-dev \
       ninja-build \
       ninja-build \
       pkg-config \
       pkg-config \
       rsync \
       rsync \

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

@@ -27,7 +27,7 @@ rm -rf ./libs
 mkdir -p ./libs/mORMot/static
 mkdir -p ./libs/mORMot/static
 # echo "Getting the latest pre-release URL..."
 # echo "Getting the latest pre-release URL..."
 # USED_TAG=$(wget -qO- https://api.github.com/repos/synopse/mORMot2/releases/latest | jq -r '.tag_name')
 # USED_TAG=$(wget -qO- https://api.github.com/repos/synopse/mORMot2/releases/latest | jq -r '.tag_name')
-USED_TAG="2.1.stable"
+USED_TAG="2.2.stable"
 
 
 echo "Used release tag $USED_TAG"
 echo "Used release tag $USED_TAG"
 URL="https://github.com/synopse/mORMot2/releases/download/$USED_TAG/mormot2static.tgz"
 URL="https://github.com/synopse/mORMot2/releases/download/$USED_TAG/mormot2static.tgz"
@@ -35,7 +35,7 @@ echo "Download statics from $URL ..."
 wget -qO- "$URL" | tar -xz -C ./libs/mORMot/static
 wget -qO- "$URL" | tar -xz -C ./libs/mORMot/static
 
 
 # uncomment for fixed commit URL
 # uncomment for fixed commit URL
-URL=https://github.com/synopse/mORMot2/tarball/c68d24054ffd3e5d63ecb33a2eea49055948e816
+URL=https://github.com/synopse/mORMot2/tarball/7dc50900266f07454fe60b60e4a2755ce445ddeb
 #URL="https://api.github.com/repos/synopse/mORMot2/tarball/$USED_TAG"
 #URL="https://api.github.com/repos/synopse/mORMot2/tarball/$USED_TAG"
 echo "Download and unpacking mORMot sources from $URL ..."
 echo "Download and unpacking mORMot sources from $URL ..."
 wget -qO- "$URL" | tar -xz -C ./libs/mORMot  --strip-components=1
 wget -qO- "$URL" | tar -xz -C ./libs/mORMot  --strip-components=1

+ 13 - 8
frameworks/Pascal/mormot/src/raw.pas

@@ -46,7 +46,7 @@ uses
 type
 type
   // data structures
   // data structures
   TMessageRec = packed record
   TMessageRec = packed record
-    message: RawUtf8;
+    message: PUtf8Char;
   end;
   end;
   TWorldRec = packed record
   TWorldRec = packed record
     id: integer;
     id: integer;
@@ -55,7 +55,7 @@ type
   TWorlds = array of TWorldRec;
   TWorlds = array of TWorldRec;
   TFortune = packed record
   TFortune = packed record
     id: integer;
     id: integer;
-    message: RawUtf8;
+    message: PUtf8Char;
   end;
   end;
   TFortunes = array of TFortune;
   TFortunes = array of TFortune;
 
 
@@ -277,6 +277,7 @@ var
   arr: TDynArray;
   arr: TDynArray;
   n: integer;
   n: integer;
   f: ^TFortune;
   f: ^TFortune;
+  mus: TSynMustacheContextData;
 begin
 begin
   result := HTTP_BADREQUEST;
   result := HTTP_BADREQUEST;
   if stmt = nil then
   if stmt = nil then
@@ -286,13 +287,16 @@ begin
   begin
   begin
     f := arr.NewPtr;
     f := arr.NewPtr;
     f.id := stmt.ColumnInt(0);
     f.id := stmt.ColumnInt(0);
-    f.message := stmt.ColumnUtf8(1);
+    f.message := stmt.ColumnPUtf8(1);
   end;
   end;
   f := arr.NewPtr;
   f := arr.NewPtr;
   f.id := 0;
   f.id := 0;
   f.message := FORTUNES_MESSAGE;
   f.message := FORTUNES_MESSAGE;
   arr.Sort(FortuneCompareByMessage);
   arr.Sort(FortuneCompareByMessage);
-  ctxt.OutContent := fTemplate.RenderDataArray(arr);
+  mus := stmt.Connection.GetThreadOwned(TSynMustacheContextData);
+  if mus = nil then
+    mus := stmt.Connection.SetThreadOwned(fTemplate.NewMustacheContextData);
+  ctxt.OutContent := mus.RenderArray(arr);
   ctxt.OutContentType := HTML_CONTENT_TYPE;
   ctxt.OutContentType := HTML_CONTENT_TYPE;
   result := HTTP_SUCCESS;
   result := HTTP_SUCCESS;
 end;
 end;
@@ -310,7 +314,7 @@ function TRawAsyncServer.json(ctxt: THttpServerRequest): cardinal;
 var
 var
   msgRec: TMessageRec;
   msgRec: TMessageRec;
 begin
 begin
-  msgRec.message := HELLO_WORLD;
+  msgRec.message := pointer(HELLO_WORLD);
   ctxt.SetOutJson(@msgRec, TypeInfo(TMessageRec));
   ctxt.SetOutJson(@msgRec, TypeInfo(TMessageRec));
   result := HTTP_SUCCESS;
   result := HTTP_SUCCESS;
 end;
 end;
@@ -471,7 +475,8 @@ begin
     W := TTextWriter.CreateOwnedStream(tmp{%H-});
     W := TTextWriter.CreateOwnedStream(tmp{%H-});
     try
     try
       W.AddShort('UPDATE world SET randomNumber = v.randomNumber FROM (VALUES');
       W.AddShort('UPDATE world SET randomNumber = v.randomNumber FROM (VALUES');
-      for i := 1 to cnt do begin
+      for i := 1 to cnt do
+      begin
         W.AddShort('(?::integer, ?::integer)');
         W.AddShort('(?::integer, ?::integer)');
         W.Add(',');
         W.Add(',');
       end;
       end;
@@ -702,9 +707,9 @@ begin
 
 
   // register some RTTI for records JSON serialization
   // register some RTTI for records JSON serialization
   Rtti.RegisterFromText([
   Rtti.RegisterFromText([
-    TypeInfo(TMessageRec), 'message:RawUtf8',
+    TypeInfo(TMessageRec), 'message:PUtf8Char',
     TypeInfo(TWorldRec),   'id,randomNumber:integer',
     TypeInfo(TWorldRec),   'id,randomNumber:integer',
-    TypeInfo(TFortune),    'id:integer message:RawUtf8']);
+    TypeInfo(TFortune),    'id:integer message:PUtf8Char']);
 
 
   // compute default execution context from HW information
   // compute default execution context from HW information
   cpuCount := CurrentCpuSet(cpuMask); // may run from a "taskset" command
   cpuCount := CurrentCpuSet(cpuMask); // may run from a "taskset" command

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

@@ -4,7 +4,7 @@ aiopg==0.7.0
 -e git+https://github.com/Eyepea/API-Hour.git@577abbdcbb8cc2810dad46e260b338b15db4d0e3#egg=api_hour-master
 -e git+https://github.com/Eyepea/API-Hour.git@577abbdcbb8cc2810dad46e260b338b15db4d0e3#egg=api_hour-master
 asyncio-redis==0.13.4
 asyncio-redis==0.13.4
 chardet==2.3.0
 chardet==2.3.0
-gunicorn==19.9.0
+gunicorn==22.0.0
 hiredis==0.2.0
 hiredis==0.2.0
 Jinja2==3.1.3
 Jinja2==3.1.3
 MarkupSafe==0.23
 MarkupSafe==0.23

+ 1 - 1
frameworks/Python/blacksheep/requirements-gunicorn.txt

@@ -1 +1 @@
-gunicorn==20.1.0
+gunicorn==22.0.0

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

@@ -1,4 +1,4 @@
 asyncpg==0.29.0
 asyncpg==0.29.0
 heaven==0.2.4
 heaven==0.2.4
 orjson==3.9.15
 orjson==3.9.15
-gunicorn==20.1.0
+gunicorn==22.0.0

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

@@ -5,7 +5,7 @@ jinja2==3.1.2
 
 
 asyncpg==0.29.0
 asyncpg==0.29.0
 
 
-gunicorn==21.2.0
+gunicorn==22.0.0
 uvicorn==0.24.0
 uvicorn==0.24.0
 uvloop==0.19.0
 uvloop==0.19.0
 httptools==0.6.1
 httptools==0.6.1

+ 3 - 1
frameworks/Python/pyramid/requirements.txt

@@ -8,12 +8,14 @@ chameleon==3.9.1
     # via pyramid-chameleon
     # via pyramid-chameleon
 greenlet==1.1.2
 greenlet==1.1.2
     # via sqlalchemy
     # via sqlalchemy
-gunicorn==20.1.0
+gunicorn==22.0.0
     # via -r requirements.in
     # via -r requirements.in
 hupper==1.10.3
 hupper==1.10.3
     # via pyramid
     # via pyramid
 orjson==3.9.15
 orjson==3.9.15
     # via -r requirements.in
     # via -r requirements.in
+packaging==24.0
+    # via gunicorn
 pastedeploy==2.1.1
 pastedeploy==2.1.1
     # via plaster-pastedeploy
     # via plaster-pastedeploy
 plaster==1.0
 plaster==1.0

+ 1 - 1
frameworks/Python/quart/requirements-uvicorn.txt

@@ -1,5 +1,5 @@
 anyio==3.6.1
 anyio==3.6.1
-gunicorn==20.1.0
+gunicorn==22.0.0
 httptools==0.4.0
 httptools==0.4.0
 idna==3.7
 idna==3.7
 python-dotenv==0.20.0
 python-dotenv==0.20.0

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

@@ -1,5 +1,5 @@
 asyncpg==0.21.0
 asyncpg==0.21.0
-gunicorn==20.0.4
+gunicorn==22.0.0
 Jinja2==3.1.3
 Jinja2==3.1.3
 ujson==2.0.3
 ujson==2.0.3
 uvloop==0.17.0
 uvloop==0.17.0

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

@@ -1,7 +1,7 @@
 asgiref==3.4.1
 asgiref==3.4.1
 asyncpg==0.24.0
 asyncpg==0.24.0
 click==8.0.1
 click==8.0.1
-gunicorn==20.1.0
+gunicorn==22.0.0
 h11==0.12.0
 h11==0.12.0
 Jinja2==3.1.3
 Jinja2==3.1.3
 MarkupSafe==2.0.1
 MarkupSafe==2.0.1

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

@@ -1,5 +1,5 @@
 asyncpg==0.28.0
 asyncpg==0.28.0
-gunicorn==20.1.0
+gunicorn==22.0.0
 httptools==0.6.0
 httptools==0.6.0
 Jinja2==3.1.3
 Jinja2==3.1.3
 ujson==5.8.0
 ujson==5.8.0

+ 2 - 1
frameworks/Ruby/h2o_mruby/h2o_mruby.dockerfile

@@ -1,4 +1,4 @@
-ARG UBUNTU_VERSION=22.04
+ARG UBUNTU_VERSION=24.04
 
 
 ARG H2O_PREFIX=/opt/h2o
 ARG H2O_PREFIX=/opt/h2o
 
 
@@ -22,6 +22,7 @@ RUN apt-get -yqq update && \
       libuv1-dev \
       libuv1-dev \
       libwslay-dev \
       libwslay-dev \
       libz-dev \
       libz-dev \
+      llvm-dev \
       ninja-build \
       ninja-build \
       pkg-config \
       pkg-config \
       rsync \
       rsync \

+ 175 - 173
frameworks/Rust/ohkami/Cargo.lock

@@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
 
 
 [[package]]
 [[package]]
 name = "ahash"
 name = "ahash"
-version = "0.8.8"
+version = "0.8.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff"
+checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
 dependencies = [
 dependencies = [
  "cfg-if",
  "cfg-if",
  "getrandom",
  "getrandom",
@@ -32,18 +32,18 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "aho-corasick"
 name = "aho-corasick"
-version = "1.1.2"
+version = "1.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
 dependencies = [
 dependencies = [
  "memchr",
  "memchr",
 ]
 ]
 
 
 [[package]]
 [[package]]
 name = "allocator-api2"
 name = "allocator-api2"
-version = "0.2.16"
+version = "0.2.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
+checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
 
 
 [[package]]
 [[package]]
 name = "annotate-snippets"
 name = "annotate-snippets"
@@ -64,27 +64,17 @@ dependencies = [
  "num-traits",
  "num-traits",
 ]
 ]
 
 
-[[package]]
-name = "atomic-write-file"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edcdbedc2236483ab103a53415653d6b4442ea6141baf1ffa85df29635e88436"
-dependencies = [
- "nix",
- "rand",
-]
-
 [[package]]
 [[package]]
 name = "autocfg"
 name = "autocfg"
-version = "1.1.0"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
 
 
 [[package]]
 [[package]]
 name = "backtrace"
 name = "backtrace"
-version = "0.3.69"
+version = "0.3.71"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
+checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
 dependencies = [
 dependencies = [
  "addr2line",
  "addr2line",
  "cc",
  "cc",
@@ -115,9 +105,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 
 [[package]]
 [[package]]
 name = "bitflags"
 name = "bitflags"
-version = "2.4.2"
+version = "2.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
+checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
 dependencies = [
 dependencies = [
  "serde",
  "serde",
 ]
 ]
@@ -133,9 +123,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "byte_reader"
 name = "byte_reader"
-version = "2.0.0"
+version = "3.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "087a18fc062e9ae6d8c0fc7d9afc22e373f3eda1244379eefabff7e2b2cad206"
+checksum = "0fac67f5455e694831246ed9a2d62c98dbb7586281dcfaba6621888ac9b576df"
 
 
 [[package]]
 [[package]]
 name = "byteorder"
 name = "byteorder"
@@ -145,18 +135,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
 
 [[package]]
 [[package]]
 name = "bytes"
 name = "bytes"
-version = "1.5.0"
+version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
+checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
 
 
 [[package]]
 [[package]]
 name = "cc"
 name = "cc"
-version = "1.0.83"
+version = "1.0.94"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
-dependencies = [
- "libc",
-]
+checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7"
 
 
 [[package]]
 [[package]]
 name = "cfg-if"
 name = "cfg-if"
@@ -203,9 +190,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "crc"
 name = "crc"
-version = "3.0.1"
+version = "3.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe"
+checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636"
 dependencies = [
 dependencies = [
  "crc-catalog",
  "crc-catalog",
 ]
 ]
@@ -243,9 +230,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "der"
 name = "der"
-version = "0.7.8"
+version = "0.7.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c"
+checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0"
 dependencies = [
 dependencies = [
  "const-oid",
  "const-oid",
  "pem-rfc7468",
  "pem-rfc7468",
@@ -291,9 +278,9 @@ checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653"
 
 
 [[package]]
 [[package]]
 name = "either"
 name = "either"
-version = "1.10.0"
+version = "1.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
+checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2"
 dependencies = [
 dependencies = [
  "serde",
  "serde",
 ]
 ]
@@ -333,9 +320,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
 
 
 [[package]]
 [[package]]
 name = "fastrand"
 name = "fastrand"
-version = "2.0.1"
+version = "2.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
+checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
 
 
 [[package]]
 [[package]]
 name = "finl_unicode"
 name = "finl_unicode"
@@ -430,7 +417,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
 dependencies = [
 dependencies = [
  "proc-macro2",
  "proc-macro2",
  "quote",
  "quote",
- "syn 2.0.49",
+ "syn 2.0.58",
 ]
 ]
 
 
 [[package]]
 [[package]]
@@ -474,9 +461,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "getrandom"
 name = "getrandom"
-version = "0.2.12"
+version = "0.2.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
+checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c"
 dependencies = [
 dependencies = [
  "cfg-if",
  "cfg-if",
  "libc",
  "libc",
@@ -519,9 +506,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "hermit-abi"
 name = "hermit-abi"
-version = "0.3.6"
+version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd"
+checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
 
 
 [[package]]
 [[package]]
 name = "hex"
 name = "hex"
@@ -568,9 +555,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "indexmap"
 name = "indexmap"
-version = "2.2.3"
+version = "2.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177"
+checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
 dependencies = [
 dependencies = [
  "equivalent",
  "equivalent",
  "hashbrown",
  "hashbrown",
@@ -587,9 +574,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "itoa"
 name = "itoa"
-version = "1.0.10"
+version = "1.0.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
+checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
 
 
 [[package]]
 [[package]]
 name = "lazy_static"
 name = "lazy_static"
@@ -641,9 +628,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "log"
 name = "log"
-version = "0.4.20"
+version = "0.4.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
+checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
 
 
 [[package]]
 [[package]]
 name = "md-5"
 name = "md-5"
@@ -657,9 +644,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "memchr"
 name = "memchr"
-version = "2.7.1"
+version = "2.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
+checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
 
 
 [[package]]
 [[package]]
 name = "minimal-lexical"
 name = "minimal-lexical"
@@ -678,9 +665,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "mio"
 name = "mio"
-version = "0.8.10"
+version = "0.8.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09"
+checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
 dependencies = [
 dependencies = [
  "libc",
  "libc",
  "wasi",
  "wasi",
@@ -705,17 +692,6 @@ dependencies = [
  "tempfile",
  "tempfile",
 ]
 ]
 
 
-[[package]]
-name = "nix"
-version = "0.27.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
-dependencies = [
- "bitflags 2.4.2",
- "cfg-if",
- "libc",
-]
-
 [[package]]
 [[package]]
 name = "nom"
 name = "nom"
 version = "7.1.3"
 version = "7.1.3"
@@ -794,14 +770,15 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "ohkami"
 name = "ohkami"
-version = "0.15.0"
+version = "0.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e19a311d70d741f4a08f54374df6501bc2ebde819b5a69b95763ea2335f5f19"
+checksum = "5eabbddbe02f121e8b6bcaa10bebcc5b42eee2b0a749ce0801a1b0d304fa6006"
 dependencies = [
 dependencies = [
  "byte_reader",
  "byte_reader",
  "hmac",
  "hmac",
  "ohkami_lib",
  "ohkami_lib",
  "ohkami_macros",
  "ohkami_macros",
+ "rustc-hash",
  "serde",
  "serde",
  "serde_json",
  "serde_json",
  "sha2",
  "sha2",
@@ -822,15 +799,20 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "ohkami_lib"
 name = "ohkami_lib"
-version = "0.1.1"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8bf187aa0f73c2b91d9ac5c7eb1437c8d1a015d765d4fc3db8113c90a82ae2a0"
+checksum = "7231554f893051d7d645c8c2d07b85e80e96f2f5c39d1a5c8568c63560815d44"
+dependencies = [
+ "byte_reader",
+ "percent-encoding",
+ "serde",
+]
 
 
 [[package]]
 [[package]]
 name = "ohkami_macros"
 name = "ohkami_macros"
-version = "0.6.0"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02c09a65693c4398af64b085040fe937f7d42d9b164306b5271fc169fa276db7"
+checksum = "6cd88e0259e3e0d02df2d44d5419fa1e3d639c4b5117d5fb6b7f281f7fa670c6"
 dependencies = [
 dependencies = [
  "proc-macro2",
  "proc-macro2",
  "quote",
  "quote",
@@ -845,11 +827,11 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
 
 
 [[package]]
 [[package]]
 name = "openssl"
 name = "openssl"
-version = "0.10.63"
+version = "0.10.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8"
+checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f"
 dependencies = [
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "cfg-if",
  "cfg-if",
  "foreign-types",
  "foreign-types",
  "libc",
  "libc",
@@ -866,7 +848,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
 dependencies = [
 dependencies = [
  "proc-macro2",
  "proc-macro2",
  "quote",
  "quote",
- "syn 2.0.49",
+ "syn 2.0.58",
 ]
 ]
 
 
 [[package]]
 [[package]]
@@ -877,9 +859,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
 
 
 [[package]]
 [[package]]
 name = "openssl-sys"
 name = "openssl-sys"
-version = "0.9.99"
+version = "0.9.102"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae"
+checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2"
 dependencies = [
 dependencies = [
  "cc",
  "cc",
  "libc",
  "libc",
@@ -933,9 +915,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
 
 
 [[package]]
 [[package]]
 name = "pin-project-lite"
 name = "pin-project-lite"
-version = "0.2.13"
+version = "0.2.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
+checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
 
 
 [[package]]
 [[package]]
 name = "pin-utils"
 name = "pin-utils"
@@ -988,18 +970,18 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "proc-macro2"
 name = "proc-macro2"
-version = "1.0.78"
+version = "1.0.79"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
+checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
 dependencies = [
 dependencies = [
  "unicode-ident",
  "unicode-ident",
 ]
 ]
 
 
 [[package]]
 [[package]]
 name = "quote"
 name = "quote"
-version = "1.0.35"
+version = "1.0.36"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
+checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
 dependencies = [
 dependencies = [
  "proc-macro2",
  "proc-macro2",
 ]
 ]
@@ -1045,9 +1027,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "regex"
 name = "regex"
-version = "1.10.3"
+version = "1.10.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
+checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
 dependencies = [
 dependencies = [
  "aho-corasick",
  "aho-corasick",
  "memchr",
  "memchr",
@@ -1057,9 +1039,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "regex-automata"
 name = "regex-automata"
-version = "0.4.5"
+version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd"
+checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
 dependencies = [
 dependencies = [
  "aho-corasick",
  "aho-corasick",
  "memchr",
  "memchr",
@@ -1068,9 +1050,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "regex-syntax"
 name = "regex-syntax"
-version = "0.8.2"
+version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
+checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
 
 
 [[package]]
 [[package]]
 name = "rsa"
 name = "rsa"
@@ -1098,6 +1080,12 @@ version = "0.1.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
 checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
 
 
+[[package]]
+name = "rustc-hash"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
 [[package]]
 [[package]]
 name = "rustc_version"
 name = "rustc_version"
 version = "0.4.0"
 version = "0.4.0"
@@ -1109,11 +1097,11 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "rustix"
 name = "rustix"
-version = "0.38.31"
+version = "0.38.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
+checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89"
 dependencies = [
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "errno",
  "errno",
  "libc",
  "libc",
  "linux-raw-sys",
  "linux-raw-sys",
@@ -1122,9 +1110,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "ryu"
 name = "ryu"
-version = "1.0.16"
+version = "1.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
+checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
 
 
 [[package]]
 [[package]]
 name = "schannel"
 name = "schannel"
@@ -1143,9 +1131,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
 
 
 [[package]]
 [[package]]
 name = "security-framework"
 name = "security-framework"
-version = "2.9.2"
+version = "2.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de"
+checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6"
 dependencies = [
 dependencies = [
  "bitflags 1.3.2",
  "bitflags 1.3.2",
  "core-foundation",
  "core-foundation",
@@ -1156,9 +1144,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "security-framework-sys"
 name = "security-framework-sys"
-version = "2.9.1"
+version = "2.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a"
+checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef"
 dependencies = [
 dependencies = [
  "core-foundation-sys",
  "core-foundation-sys",
  "libc",
  "libc",
@@ -1172,29 +1160,29 @@ checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
 
 
 [[package]]
 [[package]]
 name = "serde"
 name = "serde"
-version = "1.0.196"
+version = "1.0.197"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
+checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
 dependencies = [
 dependencies = [
  "serde_derive",
  "serde_derive",
 ]
 ]
 
 
 [[package]]
 [[package]]
 name = "serde_derive"
 name = "serde_derive"
-version = "1.0.196"
+version = "1.0.197"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
+checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
 dependencies = [
 dependencies = [
  "proc-macro2",
  "proc-macro2",
  "quote",
  "quote",
- "syn 2.0.49",
+ "syn 2.0.58",
 ]
 ]
 
 
 [[package]]
 [[package]]
 name = "serde_json"
 name = "serde_json"
-version = "1.0.113"
+version = "1.0.115"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79"
+checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd"
 dependencies = [
 dependencies = [
  "itoa",
  "itoa",
  "ryu",
  "ryu",
@@ -1253,18 +1241,18 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "smallvec"
 name = "smallvec"
-version = "1.13.1"
+version = "1.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
+checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
 
 
 [[package]]
 [[package]]
 name = "socket2"
 name = "socket2"
-version = "0.5.5"
+version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
+checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871"
 dependencies = [
 dependencies = [
  "libc",
  "libc",
- "windows-sys 0.48.0",
+ "windows-sys 0.52.0",
 ]
 ]
 
 
 [[package]]
 [[package]]
@@ -1305,9 +1293,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "sqlx"
 name = "sqlx"
-version = "0.7.3"
+version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf"
+checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa"
 dependencies = [
 dependencies = [
  "sqlx-core",
  "sqlx-core",
  "sqlx-macros",
  "sqlx-macros",
@@ -1318,9 +1306,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "sqlx-core"
 name = "sqlx-core"
-version = "0.7.3"
+version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd"
+checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6"
 dependencies = [
 dependencies = [
  "ahash",
  "ahash",
  "atoi",
  "atoi",
@@ -1328,7 +1316,6 @@ dependencies = [
  "bytes",
  "bytes",
  "crc",
  "crc",
  "crossbeam-queue",
  "crossbeam-queue",
- "dotenvy",
  "either",
  "either",
  "event-listener",
  "event-listener",
  "futures-channel",
  "futures-channel",
@@ -1359,9 +1346,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "sqlx-macros"
 name = "sqlx-macros"
-version = "0.7.3"
+version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5"
+checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127"
 dependencies = [
 dependencies = [
  "proc-macro2",
  "proc-macro2",
  "quote",
  "quote",
@@ -1372,11 +1359,10 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "sqlx-macros-core"
 name = "sqlx-macros-core"
-version = "0.7.3"
+version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841"
+checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8"
 dependencies = [
 dependencies = [
- "atomic-write-file",
  "dotenvy",
  "dotenvy",
  "either",
  "either",
  "heck",
  "heck",
@@ -1399,13 +1385,13 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "sqlx-mysql"
 name = "sqlx-mysql"
-version = "0.7.3"
+version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4"
+checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418"
 dependencies = [
 dependencies = [
  "atoi",
  "atoi",
  "base64",
  "base64",
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "byteorder",
  "byteorder",
  "bytes",
  "bytes",
  "crc",
  "crc",
@@ -1441,13 +1427,13 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "sqlx-postgres"
 name = "sqlx-postgres"
-version = "0.7.3"
+version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24"
+checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e"
 dependencies = [
 dependencies = [
  "atoi",
  "atoi",
  "base64",
  "base64",
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "byteorder",
  "byteorder",
  "crc",
  "crc",
  "dotenvy",
  "dotenvy",
@@ -1468,7 +1454,6 @@ dependencies = [
  "rand",
  "rand",
  "serde",
  "serde",
  "serde_json",
  "serde_json",
- "sha1",
  "sha2",
  "sha2",
  "smallvec",
  "smallvec",
  "sqlx-core",
  "sqlx-core",
@@ -1480,9 +1465,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "sqlx-sqlite"
 name = "sqlx-sqlite"
-version = "0.7.3"
+version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490"
+checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa"
 dependencies = [
 dependencies = [
  "atoi",
  "atoi",
  "flume",
  "flume",
@@ -1531,9 +1516,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "syn"
 name = "syn"
-version = "2.0.49"
+version = "2.0.58"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496"
+checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
 dependencies = [
 dependencies = [
  "proc-macro2",
  "proc-macro2",
  "quote",
  "quote",
@@ -1542,9 +1527,9 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "tempfile"
 name = "tempfile"
-version = "3.10.0"
+version = "3.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67"
+checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
 dependencies = [
 dependencies = [
  "cfg-if",
  "cfg-if",
  "fastrand",
  "fastrand",
@@ -1554,22 +1539,22 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "thiserror"
 name = "thiserror"
-version = "1.0.57"
+version = "1.0.58"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b"
+checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
 dependencies = [
 dependencies = [
  "thiserror-impl",
  "thiserror-impl",
 ]
 ]
 
 
 [[package]]
 [[package]]
 name = "thiserror-impl"
 name = "thiserror-impl"
-version = "1.0.57"
+version = "1.0.58"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
+checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
 dependencies = [
 dependencies = [
  "proc-macro2",
  "proc-macro2",
  "quote",
  "quote",
- "syn 2.0.49",
+ "syn 2.0.58",
 ]
 ]
 
 
 [[package]]
 [[package]]
@@ -1589,9 +1574,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
 
 
 [[package]]
 [[package]]
 name = "tokio"
 name = "tokio"
-version = "1.36.0"
+version = "1.37.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931"
+checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787"
 dependencies = [
 dependencies = [
  "backtrace",
  "backtrace",
  "bytes",
  "bytes",
@@ -1614,14 +1599,14 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
 dependencies = [
 dependencies = [
  "proc-macro2",
  "proc-macro2",
  "quote",
  "quote",
- "syn 2.0.49",
+ "syn 2.0.58",
 ]
 ]
 
 
 [[package]]
 [[package]]
 name = "tokio-stream"
 name = "tokio-stream"
-version = "0.1.14"
+version = "0.1.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842"
+checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af"
 dependencies = [
 dependencies = [
  "futures-core",
  "futures-core",
  "pin-project-lite",
  "pin-project-lite",
@@ -1657,7 +1642,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
 dependencies = [
 dependencies = [
  "proc-macro2",
  "proc-macro2",
  "quote",
  "quote",
- "syn 2.0.49",
+ "syn 2.0.58",
 ]
 ]
 
 
 [[package]]
 [[package]]
@@ -1689,9 +1674,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
 
 
 [[package]]
 [[package]]
 name = "unicode-normalization"
 name = "unicode-normalization"
-version = "0.1.22"
+version = "0.1.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
+checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
 dependencies = [
 dependencies = [
  "tinyvec",
  "tinyvec",
 ]
 ]
@@ -1771,11 +1756,21 @@ version = "0.11.0+wasi-snapshot-preview1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 
+[[package]]
+name = "wasite"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
+
 [[package]]
 [[package]]
 name = "whoami"
 name = "whoami"
-version = "1.4.1"
+version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50"
+checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9"
+dependencies = [
+ "redox_syscall",
+ "wasite",
+]
 
 
 [[package]]
 [[package]]
 name = "winapi"
 name = "winapi"
@@ -1814,7 +1809,7 @@ version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
 checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
 dependencies = [
 dependencies = [
- "windows-targets 0.52.0",
+ "windows-targets 0.52.5",
 ]
 ]
 
 
 [[package]]
 [[package]]
@@ -1834,17 +1829,18 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "windows-targets"
 name = "windows-targets"
-version = "0.52.0"
+version = "0.52.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
+checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
 dependencies = [
 dependencies = [
- "windows_aarch64_gnullvm 0.52.0",
- "windows_aarch64_msvc 0.52.0",
- "windows_i686_gnu 0.52.0",
- "windows_i686_msvc 0.52.0",
- "windows_x86_64_gnu 0.52.0",
- "windows_x86_64_gnullvm 0.52.0",
- "windows_x86_64_msvc 0.52.0",
+ "windows_aarch64_gnullvm 0.52.5",
+ "windows_aarch64_msvc 0.52.5",
+ "windows_i686_gnu 0.52.5",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc 0.52.5",
+ "windows_x86_64_gnu 0.52.5",
+ "windows_x86_64_gnullvm 0.52.5",
+ "windows_x86_64_msvc 0.52.5",
 ]
 ]
 
 
 [[package]]
 [[package]]
@@ -1855,9 +1851,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
 
 
 [[package]]
 [[package]]
 name = "windows_aarch64_gnullvm"
 name = "windows_aarch64_gnullvm"
-version = "0.52.0"
+version = "0.52.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
+checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
 
 
 [[package]]
 [[package]]
 name = "windows_aarch64_msvc"
 name = "windows_aarch64_msvc"
@@ -1867,9 +1863,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
 
 
 [[package]]
 [[package]]
 name = "windows_aarch64_msvc"
 name = "windows_aarch64_msvc"
-version = "0.52.0"
+version = "0.52.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
+checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
 
 
 [[package]]
 [[package]]
 name = "windows_i686_gnu"
 name = "windows_i686_gnu"
@@ -1879,9 +1875,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
 
 
 [[package]]
 [[package]]
 name = "windows_i686_gnu"
 name = "windows_i686_gnu"
-version = "0.52.0"
+version = "0.52.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
+checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
 
 
 [[package]]
 [[package]]
 name = "windows_i686_msvc"
 name = "windows_i686_msvc"
@@ -1891,9 +1893,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
 
 
 [[package]]
 [[package]]
 name = "windows_i686_msvc"
 name = "windows_i686_msvc"
-version = "0.52.0"
+version = "0.52.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
+checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
 
 
 [[package]]
 [[package]]
 name = "windows_x86_64_gnu"
 name = "windows_x86_64_gnu"
@@ -1903,9 +1905,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
 
 
 [[package]]
 [[package]]
 name = "windows_x86_64_gnu"
 name = "windows_x86_64_gnu"
-version = "0.52.0"
+version = "0.52.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
+checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
 
 
 [[package]]
 [[package]]
 name = "windows_x86_64_gnullvm"
 name = "windows_x86_64_gnullvm"
@@ -1915,9 +1917,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
 
 
 [[package]]
 [[package]]
 name = "windows_x86_64_gnullvm"
 name = "windows_x86_64_gnullvm"
-version = "0.52.0"
+version = "0.52.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
+checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
 
 
 [[package]]
 [[package]]
 name = "windows_x86_64_msvc"
 name = "windows_x86_64_msvc"
@@ -1927,9 +1929,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
 
 
 [[package]]
 [[package]]
 name = "windows_x86_64_msvc"
 name = "windows_x86_64_msvc"
-version = "0.52.0"
+version = "0.52.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
+checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
 
 
 [[package]]
 [[package]]
 name = "yansi-term"
 name = "yansi-term"
@@ -2042,7 +2044,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
 dependencies = [
 dependencies = [
  "proc-macro2",
  "proc-macro2",
  "quote",
  "quote",
- "syn 2.0.49",
+ "syn 2.0.58",
 ]
 ]
 
 
 [[package]]
 [[package]]

+ 3 - 3
frameworks/Rust/ohkami/Cargo.toml

@@ -5,9 +5,9 @@ edition = "2021"
 authors = ["kanarus <[email protected]>"]
 authors = ["kanarus <[email protected]>"]
 
 
 [dependencies]
 [dependencies]
-ohkami       = { version = "=0.15.0", features = ["rt_tokio"] }
-tokio        = { version = "1.36.0" , features = ["full"] }
+ohkami       = { version = "=0.16.0", features = ["rt_tokio"] }
+tokio        = { version = "1.37.0" , features = ["full"] }
 rand         = { version = "0.8.5"  , features = ["small_rng"] }
 rand         = { version = "0.8.5"  , features = ["small_rng"] }
-sqlx         = { version = "0.7.3"  , features = ["postgres", "macros", "runtime-tokio-native-tls"] }
+sqlx         = { version = "0.7.4"  , features = ["postgres", "macros", "runtime-tokio-native-tls"] }
 yarte        = { version = "0.15.7" }
 yarte        = { version = "0.15.7" }
 futures-util = { version = "0.3.30" }
 futures-util = { version = "0.3.30" }

+ 5 - 5
frameworks/Rust/ohkami/src/main.rs

@@ -7,18 +7,18 @@ pub use postgres::Postgres;
 mod templates;
 mod templates;
 pub use templates::FortunesTemplate;
 pub use templates::FortunesTemplate;
 
 
-use ohkami::{Ohkami, Route, Memory};
+use ohkami::prelude::*;
+use ohkami::Memory;
 
 
 
 
 #[tokio::main]
 #[tokio::main]
 async fn main() {
 async fn main() {
+    #[derive(Clone)]
     struct SetServer;
     struct SetServer;
-    impl ohkami::BackFang for SetServer {
-        type Error = std::convert::Infallible;
+    impl FangAction for SetServer {
         #[inline(always)]
         #[inline(always)]
-        async fn bite(&self, res: &mut ohkami::Response, _req: &ohkami::Request) -> Result<(), Self::Error> {
+        async fn back<'a>(&'a self, res: &'a mut ohkami::Response) {
             res.headers.set().Server("ohkami");
             res.headers.set().Server("ohkami");
-            Ok(())
         }
         }
     }
     }
 
 

+ 4 - 3
frameworks/Rust/ohkami/src/models.rs

@@ -1,7 +1,8 @@
-use ohkami::typed::{ResponseBody, Query};
+use ohkami::typed::{Payload, Query};
+use ohkami::builtin::payload::JSON;
 
 
 
 
-#[ResponseBody(JSONS)]
+#[Payload(JSON/S)]
 pub struct Message {
 pub struct Message {
     pub message: &'static str,
     pub message: &'static str,
 }
 }
@@ -13,7 +14,7 @@ pub struct Fortune {
 }
 }
 
 
 #[derive(sqlx::FromRow)]
 #[derive(sqlx::FromRow)]
-#[ResponseBody(JSONS)]
+#[Payload(JSON/S)]
 pub struct World {
 pub struct World {
     pub id:           i32,
     pub id:           i32,
     #[serde(rename="randomNumber")]
     #[serde(rename="randomNumber")]

+ 5 - 4
frameworks/Rust/ohkami/src/postgres.rs

@@ -1,5 +1,6 @@
 use futures_util::{stream::FuturesUnordered, TryStreamExt};
 use futures_util::{stream::FuturesUnordered, TryStreamExt};
 use rand::{rngs::SmallRng, SeedableRng, Rng, thread_rng};
 use rand::{rngs::SmallRng, SeedableRng, Rng, thread_rng};
+use ohkami::{utils::FangAction, Request, Response};
 use crate::models::{World, Fortune};
 use crate::models::{World, Fortune};
 
 
 
 
@@ -7,13 +8,13 @@ use crate::models::{World, Fortune};
 pub struct Postgres(sqlx::PgPool);
 pub struct Postgres(sqlx::PgPool);
 
 
 impl Postgres {
 impl Postgres {
-    pub async fn init() -> impl ohkami::FrontFang {
+    pub async fn init() -> impl FangAction {
+        #[derive(Clone)]
         pub struct UsePostgres(Postgres);
         pub struct UsePostgres(Postgres);
 
 
-        impl ohkami::FrontFang for UsePostgres {
-            type Error = std::convert::Infallible;
+        impl FangAction for UsePostgres {
             #[inline(always)]
             #[inline(always)]
-            async fn bite(&self, req: &mut ohkami::Request) -> Result<(), Self::Error> {
+            async fn fore<'a>(&'a self, req: &'a mut Request) -> Result<(), Response> {
                 req.memorize(self.0.clone());
                 req.memorize(self.0.clone());
                 Ok(())
                 Ok(())
             }
             }

+ 10 - 7
frameworks/Rust/ohkami/src/templates.rs

@@ -1,18 +1,21 @@
-use ohkami::{Response, IntoResponse};
+use ohkami::{IntoResponse, Response};
+use yarte::Template;
 use crate::models::Fortune;
 use crate::models::Fortune;
 
 
 
 
-#[derive(yarte::Template)]
+#[derive(Template)]
 #[template(path="fortunes")]
 #[template(path="fortunes")]
 pub struct FortunesTemplate {
 pub struct FortunesTemplate {
     pub fortunes: Vec<Fortune>,
     pub fortunes: Vec<Fortune>,
 }
 }
 impl IntoResponse for FortunesTemplate {
 impl IntoResponse for FortunesTemplate {
-    #[inline(always)]
     fn into_response(self) -> Response {
     fn into_response(self) -> Response {
-        ohkami::utils::HTML(
-            <Self as yarte::Template>::call(&self)
-                .expect("Failed to render fortunes template")
-        ).into_response()
+        match self.call() {
+            Ok(template) => Response::OK().html(template),
+            Err(error)   => {
+                eprintln!("Failed to render template: {error}");
+                Response::InternalServerError()
+            }
+        }
     }
     }
 }
 }

+ 3 - 1
frameworks/Rust/rocket/.gitignore

@@ -1 +1,3 @@
-.env
+.env
+
+Cargo.lock

File diff suppressed because it is too large
+ 262 - 299
frameworks/Rust/rocket/Cargo.lock


+ 10 - 22
frameworks/Rust/rocket/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 [package]
 name = "rocket_techempower"
 name = "rocket_techempower"
-version = "0.4.0"
+version = "0.5.0"
 authors = [
 authors = [
   "Marcelo Barbosa <[email protected]>",
   "Marcelo Barbosa <[email protected]>",
   "Brendan Hansknecht <[email protected]>",
   "Brendan Hansknecht <[email protected]>",
@@ -17,27 +17,15 @@ opt-level = 3
 name = "rocket"
 name = "rocket"
 path = "src/main.rs"
 path = "src/main.rs"
 
 
-[[bin]]
-name = "rocket-diesel"
-path = "rocket-diesel/main.rs"
+# The Diesel version is broken
+#[[bin]]
+#name = "rocket-diesel"
+#path = "rocket-diesel/main.rs"
 
 
 [dependencies]
 [dependencies]
-diesel = { version = "1.4", features = ["postgres"] }
-rocket_sync_db_pools = { version = "0.1.0-rc.2", default-features = false, features = ["diesel_postgres_pool"] }
-rocket_dyn_templates = { version = "0.1.0-rc.2", features = ["handlebars"] }
-serde = { version = "1.0", features = ["derive"] }
-serde_json = "1.0"
-serde_derive = "1.0"
-dotenv = "0.15.0"
-figment = "0.10.6"
+#rocket_sync_db_pools = { version = "0.1.0", default-features = false, features = ["diesel_postgres_pool"] }
 rand = { version = "0.8", features = ["small_rng"] }
 rand = { version = "0.8", features = ["small_rng"] }
-rocket = { version = "0.5.0-rc.2", features = [ "json" ] }
-rocket_db_pools = { version = "0.1.0-rc.2", features = [ "sqlx_postgres" ] }
-sqlx = { version = "0.5.13", features = [ "postgres", "macros" ] }
-yarte = "0.15.6"
-# temp issue https://github.com/SergioBenitez/Rocket/issues/2491
-proc-macro2 = "= 1.0.51"
-async-stream = "0.3.3"
-async-trait = "0.1.53"
-futures = "0.3.21"
-futures-util = "0.3.21"
+rocket = { version = "0.5.0", features = [ "json" ] }
+rocket_db_pools = { version = "0.1.0", features = [ "sqlx_postgres" ] }
+rocket_dyn_templates = { version = "0.1.0", features = ["handlebars"] }
+sqlx = { version = "0.7", features = ["macros"] }

+ 8 - 0
frameworks/Rust/rocket/Rocket.toml

@@ -0,0 +1,8 @@
+[default]
+address = "0.0.0.0"
+port = 8000
+log_level = "off"
+
+[default.databases.hello_world]
+url = "postgres://benchmarkdbuser:benchmarkdbpass@tfb-database/hello_world"
+connect_timeout = 5

+ 50 - 49
frameworks/Rust/rocket/benchmark_config.json

@@ -1,53 +1,54 @@
 {
 {
   "framework": "rocket",
   "framework": "rocket",
   "tests": [{
   "tests": [{
-      "default": {
-        "json_url": "/json",
-        "plaintext_url": "/plaintext",
-        "db_url": "/db",
-        "fortune_url": "/fortunes",
-        "query_url": "/queries?q=",
-        "update_url": "/updates?q=",
-        "port": 8000,
-        "approach": "Realistic",
-        "classification": "Fullstack",
-        "database": "Postgres",
-        "framework": "Rocket",
-        "language": "Rust",
-        "flavor": "None",
-        "orm": "Full",
-        "platform": "Rust",
-        "webserver": "Hyper",
-        "os": "Linux",
-        "database_os": "Linux",
-        "display_name": "Rocket",
-        "notes": "",
-        "versus": "None",
-        "tags": ["broken"]
-      },
-      "diesel": {
-        "json_url": "/json",
-        "plaintext_url": "/plaintext",
-        "db_url": "/db",
-        "fortune_url": "/fortunes",
-        "query_url": "/queries?q=",
-        "update_url": "/updates?q=",
-        "port": 8000,
-        "approach": "Realistic",
-        "classification": "Fullstack",
-        "database": "Postgres",
-        "framework": "Rocket",
-        "language": "Rust",
-        "flavor": "None",
-        "orm": "Full",
-        "platform": "Rust",
-        "webserver": "Hyper",
-        "os": "Linux",
-        "database_os": "Linux",
-        "display_name": "Rocket (Diesel)",
-        "notes": "",
-        "versus": "None",
-        "tags": ["broken"]
-      }
-    }]
+    "default": {
+      "json_url": "/json",
+      "plaintext_url": "/plaintext",
+      "db_url": "/db",
+      "fortune_url": "/fortunes",
+      "query_url": "/queries?q=",
+      "update_url": "/updates?q=",
+      "port": 8000,
+      "approach": "Realistic",
+      "classification": "Fullstack",
+      "database": "Postgres",
+      "framework": "Rocket",
+      "language": "Rust",
+      "flavor": "None",
+      "orm": "Full",
+      "platform": "Rust",
+      "webserver": "Hyper",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "Rocket",
+      "notes": "",
+      "versus": "None"
+    },
+    "diesel": {
+      "json_url": "/json",
+      "plaintext_url": "/plaintext",
+      "db_url": "/db",
+      "fortune_url": "/fortunes",
+      "query_url": "/queries?q=",
+      "update_url": "/updates?q=",
+      "port": 8000,
+      "approach": "Realistic",
+      "classification": "Fullstack",
+      "database": "Postgres",
+      "framework": "Rocket",
+      "language": "Rust",
+      "flavor": "None",
+      "orm": "Full",
+      "platform": "Rust",
+      "webserver": "Hyper",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "Rocket (Diesel)",
+      "notes": "",
+      "versus": "None",
+      "tags": [
+        "broken"
+      ]
+    }
+  }]
 }
 }

+ 1 - 1
frameworks/Rust/rocket/rocket-diesel.dockerfile

@@ -1,4 +1,4 @@
-FROM rust:1.63
+FROM rust:1.76-slim
 
 
 ENV ROCKET_BENCHMARK_DATABASE_URL=postgres://benchmarkdbuser:benchmarkdbpass@tfb-database/hello_world
 ENV ROCKET_BENCHMARK_DATABASE_URL=postgres://benchmarkdbuser:benchmarkdbpass@tfb-database/hello_world
 
 

+ 1 - 7
frameworks/Rust/rocket/rocket.dockerfile

@@ -1,10 +1,4 @@
-FROM rust:1.60-slim
-
-ENV ROCKET_BENCHMARK_DATABASE_URL=postgres://benchmarkdbuser:benchmarkdbpass@tfb-database/hello_world
-
-RUN apt-get update && apt-get install -y --no-install-recommends \
-    libpq-dev \
-&& rm -rf /var/lib/apt/lists/*
+FROM rust:1.76
 
 
 ADD ./ /rocket
 ADD ./ /rocket
 WORKDIR /rocket
 WORKDIR /rocket

+ 0 - 2
frameworks/Rust/rocket/rust-toolchain.toml

@@ -1,2 +0,0 @@
-[toolchain]
-channel = "stable"

+ 67 - 104
frameworks/Rust/rocket/src/main.rs

@@ -1,24 +1,14 @@
-#[macro_use]
-extern crate rocket;
-extern crate dotenv;
-extern crate serde_derive;
-
 mod database;
 mod database;
 mod models;
 mod models;
 
 
-use std::env;
-use std::net::{IpAddr, Ipv4Addr};
+use std::fmt::Write;
 
 
-use dotenv::dotenv;
-use figment::Figment;
 use rand::{self, Rng};
 use rand::{self, Rng};
-use rocket::{Build, Rocket};
-use rocket::config::{Config, LogLevel};
-use rocket::response::content::RawHtml;
+use rocket::{launch, get, routes};
 use rocket::serde::json::Json;
 use rocket::serde::json::Json;
-use rocket_db_pools::{sqlx, Connection, Database};
-use sqlx::Acquire;
-use yarte::Template;
+use rocket_db_pools::{Connection, Database};
+use rocket_db_pools::sqlx;
+use rocket_dyn_templates::{Template, context};
 
 
 use database::HelloWorld;
 use database::HelloWorld;
 use models::{Fortune, Message, World};
 use models::{Fortune, Message, World};
@@ -28,12 +18,11 @@ fn plaintext() -> &'static str {
     "Hello, World!"
     "Hello, World!"
 }
 }
 
 
+const MESSAGE: Message = Message { message: "Hello, World!" };
+
 #[get("/json")]
 #[get("/json")]
 fn json() -> Json<models::Message> {
 fn json() -> Json<models::Message> {
-    let message = Message {
-        message: "Hello, World!".into(),
-    };
-    Json(message)
+    Json(MESSAGE)
 }
 }
 
 
 fn random_id() -> i32 {
 fn random_id() -> i32 {
@@ -42,16 +31,18 @@ fn random_id() -> i32 {
     rng.gen_range(1..=10_000)
     rng.gen_range(1..=10_000)
 }
 }
 
 
+async fn query_random_world(db: &mut Connection<HelloWorld>) -> World {
+    let world_id = random_id();
+    sqlx::query_as("SELECT id, randomnumber FROM World WHERE id = $1")
+        .bind(world_id)
+        .fetch_one(db.as_mut())
+        .await
+        .expect("Error querying world")
+}
+
 #[get("/db")]
 #[get("/db")]
 async fn db(mut db: Connection<HelloWorld>) -> Json<World> {
 async fn db(mut db: Connection<HelloWorld>) -> Json<World> {
-    let number = random_id();
-    let result: World = sqlx::query_as("SELECT id, randomnumber FROM World WHERE id = $1")
-        .bind(number)
-        .fetch_one(&mut *db)
-        .await
-        .ok()
-        .expect("error loading world");
-    Json(result)
+    Json(query_random_world(&mut db).await)
 }
 }
 
 
 #[get("/queries")]
 #[get("/queries")]
@@ -65,31 +56,19 @@ async fn queries(mut db: Connection<HelloWorld>, q: u16) -> Json<Vec<World>> {
     let mut results = Vec::with_capacity(q.into());
     let mut results = Vec::with_capacity(q.into());
 
 
     for _ in 0..q {
     for _ in 0..q {
-        let query_id = random_id();
-        let result: World = sqlx::query_as("SELECT * FROM World WHERE id = $1")
-            .bind(query_id)
-            .fetch_one(&mut *db)
-            .await
-            .ok()
-            .expect("error loading world");
-        results.push(result);
+        let world = query_random_world(&mut db).await;
+
+        results.push(world);
     }
     }
 
 
     Json(results)
     Json(results)
 }
 }
 
 
-#[derive(Template)]
-#[template(path = "fortunes.html.hbs")]
-pub struct FortunesTemplate<'a> {
-    pub fortunes: &'a Vec<Fortune>,
-}
-
 #[get("/fortunes")]
 #[get("/fortunes")]
-async fn fortunes(mut db: Connection<HelloWorld>) -> RawHtml<String> {
+async fn fortunes(mut db: Connection<HelloWorld>) -> Template {
     let mut fortunes: Vec<Fortune> = sqlx::query_as("SELECT * FROM Fortune")
     let mut fortunes: Vec<Fortune> = sqlx::query_as("SELECT * FROM Fortune")
-        .fetch_all(&mut *db)
+        .fetch_all(db.as_mut())
         .await
         .await
-        .ok()
         .expect("Could not load Fortunes");
         .expect("Could not load Fortunes");
 
 
     fortunes.push(Fortune {
     fortunes.push(Fortune {
@@ -99,13 +78,9 @@ async fn fortunes(mut db: Connection<HelloWorld>) -> RawHtml<String> {
 
 
     fortunes.sort_by(|a, b| a.message.cmp(&b.message));
     fortunes.sort_by(|a, b| a.message.cmp(&b.message));
 
 
-    RawHtml(
-        FortunesTemplate {
-            fortunes: &fortunes,
-        }
-        .call()
-        .expect("error rendering template"),
-    )
+    Template::render("fortunes", context! {
+        fortunes: fortunes
+    })
 }
 }
 
 
 #[get("/updates")]
 #[get("/updates")]
@@ -119,70 +94,57 @@ async fn updates(mut db: Connection<HelloWorld>, q: u16) -> Json<Vec<World>> {
     let mut results = Vec::with_capacity(q.into());
     let mut results = Vec::with_capacity(q.into());
 
 
     for _ in 0..q {
     for _ in 0..q {
-        let query_id = random_id();
-        let mut result: World = sqlx::query_as("SELECT * FROM World WHERE id = $1")
-            .bind(query_id)
-            .fetch_one(&mut *db)
-            .await
-            .ok()
-            .expect("World was not found");
-
-        result.random_number = random_id();
-        results.push(result);
+        let mut world = query_random_world(&mut db).await;
+
+        world.random_number = random_id();
+        results.push(world);
     }
     }
 
 
-    let mut pool = db.into_inner();
-    let mut tx = pool
-        .begin()
-        .await
-        .ok()
-        .expect("could not start transaction");
+    let query_string = {
+        let mut query = String::new();
+
+        query.push_str("UPDATE World SET randomnumber = CASE id ");
+
+        let mut pl = 1;
+
+        for _ in 1..=q {
+            let _ = write!(query, "when ${pl} then ${} ", pl + 1);
+            pl += 2;
+        }
+
+        query.push_str("ELSE randomnumber END WHERE id IN (");
+
+        for _ in 1..=q {
+            let _ = write!(query, "${pl},");
+            pl += 1;
+        }
+
+        query.pop();
+        query.push(')');
+
+        query
+    };
+
+    let mut query = sqlx::query(&query_string);
 
 
     for w in &results {
     for w in &results {
-        sqlx::query("UPDATE World SET randomnumber = $1 WHERE id = $2")
-            .bind(w.random_number)
-            .bind(w.id)
-            .execute(&mut tx)
-            .await
-            .ok()
-            .expect("Could not update World");
+        query = query.bind(w.id).bind(w.random_number);
     }
     }
 
 
-    tx.commit().await.ok().expect("could not update worlds");
+    for w in &results {
+        query = query.bind(w.id);
+    }
+
+    query.execute(db.as_mut())
+        .await
+        .expect("Could not update worlds");
 
 
     Json(results)
     Json(results)
 }
 }
 
 
 #[launch]
 #[launch]
-pub fn launch() -> Rocket<Build> {
-    if cfg!(not(test)) {
-        dotenv().ok();
-    }
-
-    let config = Config {
-        address: IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)),
-        port: 8000,
-        keep_alive: 0,
-        log_level: LogLevel::Off,
-        ..Default::default()
-    };
-
-    let database_url = env::var("ROCKET_BENCHMARK_DATABASE_URL")
-        .ok()
-        .expect("ROCKET_BENCHMARK_DATABASE_URL environment variable was not set");
-
-    let figment = Figment::from(config).merge((
-        "databases.hello_world",
-        rocket_db_pools::Config {
-            url: database_url,
-            min_connections: None,
-            max_connections: 100,
-            connect_timeout: 3,
-            idle_timeout: None,
-        },
-    ));
-
-    rocket::custom(figment)
+pub fn launch() -> _ {
+    rocket::build()
         .mount(
         .mount(
             "/",
             "/",
             routes![
             routes![
@@ -197,4 +159,5 @@ pub fn launch() -> Rocket<Build> {
             ],
             ],
         )
         )
         .attach(HelloWorld::init())
         .attach(HelloWorld::init())
+        .attach(Template::fairing())
 }
 }

+ 3 - 5
frameworks/Rust/rocket/src/models.rs

@@ -1,13 +1,12 @@
 use rocket::serde::{Deserialize, Serialize};
 use rocket::serde::{Deserialize, Serialize};
-use sqlx::FromRow;
-use std::borrow::Cow;
+use rocket_db_pools::sqlx::FromRow;
 
 
 #[derive(Serialize)]
 #[derive(Serialize)]
+#[serde(crate = "rocket::serde")]
 pub struct Message {
 pub struct Message {
-    pub message: Cow<'static, str>,
+    pub message: &'static str,
 }
 }
 
 
-#[allow(non_snake_case)]
 #[derive(Clone, Debug, PartialEq, Deserialize, Serialize, FromRow)]
 #[derive(Clone, Debug, PartialEq, Deserialize, Serialize, FromRow)]
 #[serde(crate = "rocket::serde")]
 #[serde(crate = "rocket::serde")]
 pub struct Fortune {
 pub struct Fortune {
@@ -15,7 +14,6 @@ pub struct Fortune {
     pub message: String,
     pub message: String,
 }
 }
 
 
-#[allow(non_snake_case)]
 #[derive(Clone, Debug, PartialEq, Deserialize, Serialize, FromRow)]
 #[derive(Clone, Debug, PartialEq, Deserialize, Serialize, FromRow)]
 #[serde(crate = "rocket::serde")]
 #[serde(crate = "rocket::serde")]
 pub struct World {
 pub struct World {

File diff suppressed because it is too large
+ 422 - 226
frameworks/Rust/trillium/Cargo.lock


+ 19 - 5
frameworks/Rust/trillium/Cargo.toml

@@ -5,28 +5,42 @@ edition = "2021"
 
 
 [features]
 [features]
 jemallocator = ["dep:jemallocator"]
 jemallocator = ["dep:jemallocator"]
+tokio = ["dep:trillium-tokio", "sea-orm/runtime-tokio", "sqlx/runtime-tokio"]
+smol = [
+        "dep:trillium-smol",
+        "sea-orm/runtime-async-std",
+        "sqlx/runtime-async-std",
+]
+async-std = [
+        "dep:trillium-async-std",
+        "sea-orm/runtime-async-std",
+        "sqlx/runtime-async-std",
+]
 
 
 [dependencies]
 [dependencies]
 askama = "0.12.1"
 askama = "0.12.1"
+env_logger = "0.11.3"
 fastrand = "2.0.2"
 fastrand = "2.0.2"
 futures-lite = "2.3.0"
 futures-lite = "2.3.0"
+jemallocator = { version = "0.5.4", optional = true }
+moka = { version = "0.12.5", features = ["future"] }
 serde = { version = "1.0.197", features = ["derive"] }
 serde = { version = "1.0.197", features = ["derive"] }
 serde_json = "1.0.115"
 serde_json = "1.0.115"
+sqlx = "0.7.4"
 trillium = "0.2.19"
 trillium = "0.2.19"
 trillium-api = "0.1.0"
 trillium-api = "0.1.0"
 trillium-askama = "0.3.2"
 trillium-askama = "0.3.2"
-trillium-smol = "0.4.0"
+trillium-async-std = { version = "0.4.0", optional = true }
 trillium-logger = "0.4.5"
 trillium-logger = "0.4.5"
 trillium-router = "0.4.1"
 trillium-router = "0.4.1"
+trillium-smol = { version = "0.4.0", optional = true }
+trillium-tokio = { version = "0.4.0", optional = true }
 unicycle = "0.10.1"
 unicycle = "0.10.1"
-env_logger = "0.11.3"
-moka = { version = "0.12.5", features = ["future"] }
-jemallocator = {version="0.5.4", optional = true}
 
 
 [dependencies.sea-orm]
 [dependencies.sea-orm]
 version = "0.12.15"
 version = "0.12.15"
 default-features = false
 default-features = false
-features = ["runtime-async-std-native-tls", "sqlx-postgres", "macros"]
+features = ["sqlx-postgres", "macros"]
 
 
 [profile.release]
 [profile.release]
 panic = "abort"
 panic = "abort"

+ 55 - 1
frameworks/Rust/trillium/benchmark_config.json

@@ -23,7 +23,61 @@
         "webserver": "None",
         "webserver": "None",
         "os": "Linux",
         "os": "Linux",
         "database_os": "Linux",
         "database_os": "Linux",
-        "display_name": "Trillium",
+        "display_name": "Trillium [smol]",
+        "notes": "",
+        "versus": "None",
+        "tags": ["verified"]
+      }
+    },
+    {
+      "async-std": {
+        "db_url": "/db",
+        "json_url": "/json",
+        "query_url": "/queries/",
+        "plaintext_url": "/plaintext",
+        "fortune_url": "/fortunes",
+        "cached_query_url": "/cached-queries/",
+        "update_url": "/updates/",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "database": "postgres",
+        "framework": "Trillium",
+        "language": "Rust",
+        "flavor": "None",
+        "orm": "Full",
+        "platform": "None",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "Trillium [async-std]",
+        "notes": "",
+        "versus": "None",
+        "tags": ["verified"]
+      }
+    },
+    {
+      "tokio": {
+        "db_url": "/db",
+        "json_url": "/json",
+        "query_url": "/queries/",
+        "plaintext_url": "/plaintext",
+        "fortune_url": "/fortunes",
+        "cached_query_url": "/cached-queries/",
+        "update_url": "/updates/",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "database": "postgres",
+        "framework": "Trillium",
+        "language": "Rust",
+        "flavor": "None",
+        "orm": "Full",
+        "platform": "None",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "Trillium [tokio]",
         "notes": "",
         "notes": "",
         "versus": "None",
         "versus": "None",
         "tags": ["verified"]
         "tags": ["verified"]

+ 14 - 1
frameworks/Rust/trillium/src/main.rs

@@ -8,6 +8,18 @@ mod routes;
 use application::application;
 use application::application;
 use trillium::HttpConfig;
 use trillium::HttpConfig;
 
 
+#[cfg(all(feature = "smol", not(feature = "tokio"), not(feature = "async-std")))]
+use trillium_smol::config;
+
+#[cfg(all(feature = "tokio", not(feature = "smol"), not(feature = "async-std")))]
+use trillium_tokio::config;
+
+#[cfg(all(feature = "async-std", not(feature = "smol"), not(feature = "tokio")))]
+use trillium_async_std::config;
+
+#[cfg(not(any(feature = "async-std", feature = "smol", feature = "tokio")))]
+compile_error! {"please run with one of the following --features `async-std`, `smol`, `tokio`"}
+
 fn main() {
 fn main() {
     #[cfg(debug_assertions)]
     #[cfg(debug_assertions)]
     env_logger::init();
     env_logger::init();
@@ -17,7 +29,8 @@ fn main() {
         .with_request_buffer_initial_len(256)
         .with_request_buffer_initial_len(256)
         .with_response_header_initial_capacity(5);
         .with_response_header_initial_capacity(5);
 
 
-    trillium_smol::config()
+    config()
+        .with_nodelay()
         .with_http_config(http_config)
         .with_http_config(http_config)
         .run(application())
         .run(application())
 }
 }

+ 16 - 0
frameworks/Rust/trillium/trillium-async-std.dockerfile

@@ -0,0 +1,16 @@
+FROM rust:1.77
+WORKDIR /trillium
+COPY src src
+COPY templates templates
+COPY Cargo.toml Cargo.toml
+COPY Cargo.lock Cargo.lock
+
+EXPOSE 8080
+
+ENV RUSTFLAGS="-C target-cpu=native"
+ENV PORT=8080
+ENV HOST=0.0.0.0
+ENV DATABASE_URL=postgres://benchmarkdbuser:benchmarkdbpass@tfb-database/hello_world
+
+RUN cargo build --release --features jemallocator,async-std
+CMD ["./target/release/trillium-techempower"]

+ 16 - 0
frameworks/Rust/trillium/trillium-tokio.dockerfile

@@ -0,0 +1,16 @@
+FROM rust:1.77
+WORKDIR /trillium
+COPY src src
+COPY templates templates
+COPY Cargo.toml Cargo.toml
+COPY Cargo.lock Cargo.lock
+
+EXPOSE 8080
+
+ENV RUSTFLAGS="-C target-cpu=native"
+ENV PORT=8080
+ENV HOST=0.0.0.0
+ENV DATABASE_URL=postgres://benchmarkdbuser:benchmarkdbpass@tfb-database/hello_world
+
+RUN cargo build --release --features jemallocator,tokio
+CMD ["./target/release/trillium-techempower"]

+ 2 - 2
frameworks/Rust/trillium/trillium.dockerfile

@@ -1,4 +1,4 @@
-FROM rust:1.76
+FROM rust:1.77
 WORKDIR /trillium
 WORKDIR /trillium
 COPY src src
 COPY src src
 COPY templates templates
 COPY templates templates
@@ -12,5 +12,5 @@ ENV PORT=8080
 ENV HOST=0.0.0.0
 ENV HOST=0.0.0.0
 ENV DATABASE_URL=postgres://benchmarkdbuser:benchmarkdbpass@tfb-database/hello_world
 ENV DATABASE_URL=postgres://benchmarkdbuser:benchmarkdbpass@tfb-database/hello_world
 
 
-RUN cargo build --release --features jemallocator
+RUN cargo build --release --features jemallocator,smol
 CMD ["./target/release/trillium-techempower"]
 CMD ["./target/release/trillium-techempower"]

+ 6 - 0
frameworks/Ur/urweb/bench.ur

@@ -133,3 +133,9 @@ fun updates s =
 
 
 fun plaintext () =
 fun plaintext () =
   returnText "Hello, World!"
   returnText "Hello, World!"
+
+(** * Test type 7: Cached queries *)
+
+val cached_queries = queries
+(* It's really the same code as the uncached queries test!
+ * We just compile with a different flag to enable caching. *)

+ 1 - 0
frameworks/Ur/urweb/bench.urs

@@ -4,3 +4,4 @@ val queries : string -> transaction page
 val fortunes : unit -> transaction page
 val fortunes : unit -> transaction page
 val updates : string -> transaction page
 val updates : string -> transaction page
 val plaintext : unit -> transaction page
 val plaintext : unit -> transaction page
+val cached_queries : string -> transaction page

+ 5 - 6
frameworks/Ur/urweb/benchmark_config.json

@@ -1,5 +1,6 @@
 {
 {
   "framework": "urweb",
   "framework": "urweb",
+  "maintainers": ["achlipala"],
   "tests": [{
   "tests": [{
     "default": {
     "default": {
       "display_name": "urweb",
       "display_name": "urweb",
@@ -42,7 +43,7 @@
     },
     },
     "cache": {
     "cache": {
       "setup_file": "setup-postgresql",
       "setup_file": "setup-postgresql",
-      "cached_query_url": "/queries/",
+      "cached_query_url": "/cached_queries/",
       "port": 8080,
       "port": 8080,
       "approach": "Realistic",
       "approach": "Realistic",
       "classification": "Fullstack",
       "classification": "Fullstack",
@@ -53,12 +54,11 @@
       "platform": "Ur/Web",
       "platform": "Ur/Web",
       "webserver": "None",
       "webserver": "None",
       "os": "Linux",
       "os": "Linux",
-      "database_os": "Linux",
-      "tags": ["broken"]
+      "database_os": "Linux"
     },
     },
     "mysql-cache": {
     "mysql-cache": {
       "setup_file": "setup-mysql",
       "setup_file": "setup-mysql",
-      "cached_query_url": "/queries/",
+      "cached_query_url": "/cached_queries/",
       "port": 8080,
       "port": 8080,
       "approach": "Realistic",
       "approach": "Realistic",
       "classification": "Fullstack",
       "classification": "Fullstack",
@@ -69,8 +69,7 @@
       "platform": "Ur/Web",
       "platform": "Ur/Web",
       "webserver": "None",
       "webserver": "None",
       "os": "Linux",
       "os": "Linux",
-      "database_os": "Linux",
-      "tags": ["broken"]
+      "database_os": "Linux"
     }
     }
   }]
   }]
 }
 }

+ 2 - 2
frameworks/Ur/urweb/config.toml

@@ -19,7 +19,7 @@ webserver = "None"
 versus = "None"
 versus = "None"
 
 
 [mysql-cache]
 [mysql-cache]
-urls.cached_query = "/queries/"
+urls.cached_query = "/cached_queries/"
 approach = "Realistic"
 approach = "Realistic"
 classification = "Fullstack"
 classification = "Fullstack"
 database = "MySQL"
 database = "MySQL"
@@ -31,7 +31,7 @@ webserver = "None"
 versus = "None"
 versus = "None"
 
 
 [cache]
 [cache]
-urls.cached_query = "/queries/"
+urls.cached_query = "/cached_queries/"
 approach = "Realistic"
 approach = "Realistic"
 classification = "Fullstack"
 classification = "Fullstack"
 database = "Postgres"
 database = "Postgres"

+ 2 - 2
frameworks/Ur/urweb/urweb-cache.dockerfile

@@ -1,9 +1,9 @@
-FROM ubuntu:18.04
+FROM ubuntu:23.10
 
 
 ADD ./ /urweb
 ADD ./ /urweb
 WORKDIR /urweb
 WORKDIR /urweb
 
 
-RUN apt-get update -yqq && apt-get install -yqq urweb
+RUN apt-get update -yqq && apt-get install -yqq sudo git gcc make autoconf automake libtool mlton libpq-dev libssl-dev uthash-dev libicu-dev && git clone https://github.com/urweb/urweb.git && cd urweb && ./autogen.sh && ./configure && make -j && sudo make install
 
 
 RUN urweb -sqlcache -db "dbname=hello_world user=benchmarkdbuser password=benchmarkdbpass host=tfb-database" bench
 RUN urweb -sqlcache -db "dbname=hello_world user=benchmarkdbuser password=benchmarkdbpass host=tfb-database" bench
 
 

+ 2 - 2
frameworks/Ur/urweb/urweb-mysql-cache.dockerfile

@@ -1,9 +1,9 @@
-FROM ubuntu:18.04
+FROM ubuntu:23.10
 
 
 ADD ./ /urweb
 ADD ./ /urweb
 WORKDIR /urweb
 WORKDIR /urweb
 
 
-RUN apt-get update -yqq && apt-get install -yqq urweb
+RUN apt-get update -yqq && apt-get install -yqq sudo git gcc make autoconf automake libtool mlton libmysqlclient-dev libssl-dev uthash-dev libicu-dev && git clone https://github.com/urweb/urweb.git && cd urweb && ./autogen.sh && ./configure && make -j && sudo make install
 
 
 RUN urweb -sqlcache -dbms mysql -db "dbname=hello_world user=benchmarkdbuser password=benchmarkdbpass host=tfb-database" bench
 RUN urweb -sqlcache -dbms mysql -db "dbname=hello_world user=benchmarkdbuser password=benchmarkdbpass host=tfb-database" bench
 
 

+ 2 - 2
frameworks/Ur/urweb/urweb-mysql.dockerfile

@@ -1,9 +1,9 @@
-FROM ubuntu:18.04
+FROM ubuntu:23.10
 
 
 ADD ./ /urweb
 ADD ./ /urweb
 WORKDIR /urweb
 WORKDIR /urweb
 
 
-RUN apt-get update -yqq && apt-get install -yqq urweb
+RUN apt-get update -yqq && apt-get install -yqq sudo git gcc make autoconf automake libtool mlton libmysqlclient-dev libssl-dev uthash-dev libicu-dev && git clone https://github.com/urweb/urweb.git && cd urweb && ./autogen.sh && ./configure && make -j && sudo make install
 
 
 RUN urweb -dbms mysql -db "dbname=hello_world user=benchmarkdbuser password=benchmarkdbpass host=tfb-database" bench
 RUN urweb -dbms mysql -db "dbname=hello_world user=benchmarkdbuser password=benchmarkdbpass host=tfb-database" bench
 
 

+ 2 - 2
frameworks/Ur/urweb/urweb.dockerfile

@@ -1,9 +1,9 @@
-FROM ubuntu:18.04
+FROM ubuntu:23.10
 
 
 ADD ./ /urweb
 ADD ./ /urweb
 WORKDIR /urweb
 WORKDIR /urweb
 
 
-RUN apt-get update -yqq && apt-get install -yqq urweb
+RUN apt-get update -yqq && apt-get install -yqq sudo git gcc make autoconf automake libtool mlton libpq-dev libssl-dev uthash-dev libicu-dev && git clone https://github.com/urweb/urweb.git && cd urweb && ./autogen.sh && ./configure && make -j && sudo make install
 
 
 RUN urweb -db "dbname=hello_world user=benchmarkdbuser password=benchmarkdbpass host=tfb-database" bench
 RUN urweb -db "dbname=hello_world user=benchmarkdbuser password=benchmarkdbpass host=tfb-database" bench
 
 

Some files were not shown because too many files changed in this diff