Browse Source

Merge branch 'TechEmpower:master' into master

Huang ziquan 5 months ago
parent
commit
ccae4f11db
100 changed files with 1986 additions and 696 deletions
  1. 1 1
      frameworks/CSharp/fastendpoints/Benchmarks/Benchmarks.csproj
  2. 3 2
      frameworks/CSharp/fastendpoints/Benchmarks/Endpoints/JsonEndpoint.cs
  3. 6 5
      frameworks/CSharp/fastendpoints/Benchmarks/Endpoints/PlainTextEndpoint.cs
  4. 5 5
      frameworks/CSharp/fastendpoints/Benchmarks/Program.cs
  5. 3 3
      frameworks/CSharp/fastendpoints/README.md
  6. 6 2
      frameworks/CSharp/fastendpoints/fastendpoints.dockerfile
  7. 7 8
      frameworks/CSharp/genhttp/Benchmarks/Benchmarks.csproj
  8. 4 2
      frameworks/CSharp/genhttp/Benchmarks/Program.cs
  9. 39 0
      frameworks/CSharp/genhttp/Benchmarks/Tests/JsonHandler.cs
  10. 0 20
      frameworks/CSharp/genhttp/Benchmarks/Tests/JsonResource.cs
  11. 5 0
      frameworks/CSharp/genhttp/genhttp.dockerfile
  12. 2 4
      frameworks/CSharp/sisk/benchmark_config.json
  13. 1 1
      frameworks/CSharp/sisk/config.toml
  14. 7 3
      frameworks/CSharp/sisk/sisk-cadente.dockerfile
  15. 22 14
      frameworks/CSharp/sisk/sisk-cadente/Program.cs
  16. 11 11
      frameworks/CSharp/sisk/sisk-cadente/sisk.csproj
  17. 6 2
      frameworks/CSharp/sisk/sisk/Program.cs
  18. 5 5
      frameworks/FSharp/falco/README.md
  19. 1 1
      frameworks/FSharp/falco/benchmark_config.json
  20. 4 4
      frameworks/FSharp/falco/falco.dockerfile
  21. 3 8
      frameworks/FSharp/falco/src/App/App.fsproj
  22. 0 83
      frameworks/FSharp/falco/src/App/Fortune.fs
  23. 86 11
      frameworks/FSharp/falco/src/App/Program.fs
  24. 0 47
      frameworks/FSharp/falco/src/App/Server.fs
  25. 0 11
      frameworks/FSharp/falco/src/App/UI.fs
  26. 78 0
      frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/PgClientConnection.java
  27. 11 116
      frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/PgClientConnectionPool.java
  28. 60 0
      frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/PgClientConnectionPoolArray.java
  29. 2 5
      frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/PgClientRepository.java
  30. 2 0
      frameworks/Java/helidon/nima/src/main/resources/application.yaml
  31. 1 1
      frameworks/Java/inverno/inverno-postgres.dockerfile
  32. 1 1
      frameworks/Java/inverno/inverno.dockerfile
  33. 3 3
      frameworks/Java/smart-socket/benchmark_config.json
  34. 2 2
      frameworks/Java/smart-socket/feat-smart-servlet.dockerfile
  35. 2 2
      frameworks/Java/smart-socket/feat.dockerfile
  36. 24 9
      frameworks/Java/smart-socket/pom.xml
  37. 18 17
      frameworks/Java/smart-socket/src/main/java/org/smartboot/http/Bootstrap.java
  38. 24 0
      frameworks/Java/smart-socket/src/main/java/org/smartboot/http/FeatController.java
  39. 19 0
      frameworks/Java/tio-boot/.dockerignore
  40. 3 0
      frameworks/Java/tio-boot/.gitignore
  41. 114 0
      frameworks/Java/tio-boot/README.md
  42. 227 0
      frameworks/Java/tio-boot/api/tio-server-benchmark.md
  43. 29 0
      frameworks/Java/tio-boot/benchmark_config.json
  44. 19 0
      frameworks/Java/tio-boot/config.toml
  45. 126 0
      frameworks/Java/tio-boot/pom.xml
  46. 13 0
      frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/MainApp.java
  47. 54 0
      frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/MainAppConfig.java
  48. 12 0
      frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/config/EhCachePluginConfig.java
  49. 22 0
      frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/config/EnjoyEngineConfig.java
  50. 31 0
      frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/config/MysqlDbConfig.java
  51. 41 0
      frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/controller/CacheHandler.java
  52. 126 0
      frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/controller/DbHandler.java
  53. 40 0
      frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/controller/IndexHandler.java
  54. 23 0
      frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/model/Fortune.java
  55. 12 0
      frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/model/Message.java
  56. 32 0
      frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/model/World.java
  57. 50 0
      frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/services/CacheName.java
  58. 17 0
      frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/services/CacheNameService.java
  59. 36 0
      frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/utils/RandomUtils.java
  60. 9 0
      frameworks/Java/tio-boot/src/main/resources/app.properties
  61. 9 0
      frameworks/Java/tio-boot/src/main/resources/ehcache.xml
  62. 52 0
      frameworks/Java/tio-boot/src/main/resources/logback.xml
  63. 20 0
      frameworks/Java/tio-boot/src/main/resources/templates/fortunes.html
  64. 15 0
      frameworks/Java/tio-boot/src/test/java/com/litongjava/tio/http/server/MainAppTest.java
  65. 20 0
      frameworks/Java/tio-boot/tio-boot.dockerfile
  66. 64 151
      frameworks/Java/tio-http-server/pom.xml
  67. 11 3
      frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/MainApp.java
  68. 3 3
      frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/controller/CacheController.java
  69. 10 11
      frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/controller/DbController.java
  70. 0 31
      frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/utils/BeanConverterUtils.java
  71. 3 2
      frameworks/Java/tio-http-server/tio-server.dockerfile
  72. 27 0
      frameworks/JavaScript/aroma.js/README.md
  73. 36 0
      frameworks/JavaScript/aroma.js/app.js
  74. 11 0
      frameworks/JavaScript/aroma.js/aroma.js.dockerfile
  75. 21 0
      frameworks/JavaScript/aroma.js/benchmark_config.json
  76. 13 0
      frameworks/JavaScript/aroma.js/config.toml
  77. 8 0
      frameworks/JavaScript/aroma.js/package.json
  78. 1 1
      frameworks/JavaScript/koa/package.json
  79. 4 4
      frameworks/Kotlin/hexagon/benchmark_config.json
  80. 10 10
      frameworks/Kotlin/hexagon/build.gradle
  81. 2 2
      frameworks/Kotlin/hexagon/config.toml
  82. 5 5
      frameworks/Kotlin/hexagon/core/build.gradle
  83. 6 6
      frameworks/Kotlin/hexagon/core/src/main/kotlin/Benchmark.kt
  84. 20 20
      frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt
  85. 5 5
      frameworks/Kotlin/hexagon/core/src/main/kotlin/store/BenchmarkStore.kt
  86. 4 1
      frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties
  87. 1 1
      frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.jte
  88. 1 1
      frameworks/Kotlin/hexagon/gradle/wrapper/gradle-wrapper.properties
  89. 1 2
      frameworks/Kotlin/hexagon/gradlew
  90. 4 4
      frameworks/Kotlin/hexagon/hexagon-jdk-pgclient.dockerfile
  91. 4 4
      frameworks/Kotlin/hexagon/hexagon-jdk.dockerfile
  92. 1 1
      frameworks/Kotlin/hexagon/hexagon_helidon_pgclient/build.gradle
  93. 9 9
      frameworks/Kotlin/hexagon/hexagon_helidon_pgclient/src/main/kotlin/Benchmark.kt
  94. 1 1
      frameworks/Kotlin/hexagon/hexagon_helidon_postgresql/build.gradle
  95. 8 8
      frameworks/Kotlin/hexagon/hexagon_helidon_postgresql/src/main/kotlin/Benchmark.kt
  96. 7 0
      frameworks/Kotlin/hexagon/hexagon_jdk_pgclient/build.gradle
  97. 25 0
      frameworks/Kotlin/hexagon/hexagon_jdk_pgclient/src/main/kotlin/Benchmark.kt
  98. 8 0
      frameworks/Kotlin/hexagon/hexagon_jdk_postgresql/build.gradle
  99. 25 0
      frameworks/Kotlin/hexagon/hexagon_jdk_postgresql/src/main/kotlin/Benchmark.kt
  100. 1 1
      frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/build.gradle

+ 1 - 1
frameworks/CSharp/fastendpoints/Benchmarks/Benchmarks.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk.Web">
 <Project Sdk="Microsoft.NET.Sdk.Web">
 
 
   <PropertyGroup>
   <PropertyGroup>
-    <TargetFramework>net8.0</TargetFramework>
+    <TargetFramework>net9.0</TargetFramework>
     <Nullable>enable</Nullable>
     <Nullable>enable</Nullable>
     <ImplicitUsings>enable</ImplicitUsings>
     <ImplicitUsings>enable</ImplicitUsings>
     <NoWarn>CA2016;IDE1006</NoWarn>
     <NoWarn>CA2016;IDE1006</NoWarn>

+ 3 - 2
frameworks/CSharp/fastendpoints/Benchmarks/Endpoints/JsonEndpoint.cs

@@ -1,6 +1,6 @@
 namespace Benchmarks.Endpoints;
 namespace Benchmarks.Endpoints;
 
 
-public sealed class JsonEndpoint : Endpoint<EmptyRequest, object>
+sealed class JsonEndpoint : Ep.NoReq.Res<object>
 {
 {
     public override void Configure()
     public override void Configure()
     {
     {
@@ -8,9 +8,10 @@ public sealed class JsonEndpoint : Endpoint<EmptyRequest, object>
         AllowAnonymous();
         AllowAnonymous();
     }
     }
 
 
-    public override Task HandleAsync(EmptyRequest _, CancellationToken __)
+    public override Task HandleAsync(CancellationToken ct)
     {
     {
         HttpContext.Response.ContentLength = 27;
         HttpContext.Response.ContentLength = 27;
+
         return SendAsync(new { message = "Hello, World!" });
         return SendAsync(new { message = "Hello, World!" });
     }
     }
 }
 }

+ 6 - 5
frameworks/CSharp/fastendpoints/Benchmarks/Endpoints/PlainTextEndpoint.cs

@@ -1,8 +1,8 @@
 namespace Benchmarks.Endpoints;
 namespace Benchmarks.Endpoints;
 
 
-public sealed class PlainTextEndpoint : Endpoint<EmptyRequest, EmptyResponse>
+sealed class PlainTextEndpoint : Ep.NoReq.Res<byte[]>
 {
 {
-    private static readonly byte[] payload = System.Text.Encoding.UTF8.GetBytes("Hello, World!");
+    static readonly byte[] _payload = "Hello, World!"u8.ToArray();
 
 
     public override void Configure()
     public override void Configure()
     {
     {
@@ -10,11 +10,12 @@ public sealed class PlainTextEndpoint : Endpoint<EmptyRequest, EmptyResponse>
         AllowAnonymous();
         AllowAnonymous();
     }
     }
 
 
-    public override Task HandleAsync(EmptyRequest _, CancellationToken __)
+    public override Task HandleAsync(CancellationToken ct)
     {
     {
         HttpContext.Response.StatusCode = StatusCodes.Status200OK;
         HttpContext.Response.StatusCode = StatusCodes.Status200OK;
         HttpContext.Response.ContentType = "text/plain";
         HttpContext.Response.ContentType = "text/plain";
-        HttpContext.Response.ContentLength = payload.Length;
-        return HttpContext.Response.Body.WriteAsync(payload, 0, payload.Length);
+        HttpContext.Response.ContentLength = _payload.Length;
+
+        return HttpContext.Response.Body.WriteAsync(_payload, 0, _payload.Length);
     }
     }
 }
 }

+ 5 - 5
frameworks/CSharp/fastendpoints/Benchmarks/Program.cs

@@ -1,9 +1,9 @@
 global using FastEndpoints;
 global using FastEndpoints;
 
 
-var builder = WebApplication.CreateBuilder();
-builder.Logging.ClearProviders();
-builder.Services.AddFastEndpoints();
+var bld = WebApplication.CreateBuilder();
+bld.Logging.ClearProviders();
+bld.Services.AddFastEndpoints();
 
 
-var app = builder.Build();
+var app = bld.Build();
 app.UseFastEndpoints();
 app.UseFastEndpoints();
-app.Run("http://0.0.0.0:8080");
+app.Run("http://0.0.0.0:8080");

+ 3 - 3
frameworks/CSharp/fastendpoints/README.md

@@ -5,11 +5,11 @@ This includes tests for plaintext and json serialization.
 
 
 **Language**
 **Language**
 
 
-* C# 12.0
+* C# 13.0
 
 
 **Platforms**
 **Platforms**
 
 
-* .NET 8 (Windows and Linux)
+* .NET 9 (Windows and Linux)
 
 
 **Web Servers**
 **Web Servers**
 
 
@@ -18,7 +18,7 @@ This includes tests for plaintext and json serialization.
 **Web Stack**
 **Web Stack**
 
 
 * [FastEndpoints](https://fast-endpoints.com/)
 * [FastEndpoints](https://fast-endpoints.com/)
-* ASP.NET 8
+* ASP.NET 9
 
 
 ## Paths & Source for Tests
 ## Paths & Source for Tests
 
 

+ 6 - 2
frameworks/CSharp/fastendpoints/fastendpoints.dockerfile

@@ -1,9 +1,13 @@
-FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
 WORKDIR /app
 WORKDIR /app
 COPY Benchmarks .
 COPY Benchmarks .
 RUN dotnet publish -c Release -o out
 RUN dotnet publish -c Release -o out
 
 
-FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime
+ENV DOTNET_GCDynamicAdaptationMode=0
+ENV DOTNET_ReadyToRun=0
+ENV DOTNET_HillClimbing_Disable=1
+
 WORKDIR /app
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY --from=build /app/out ./
 
 

+ 7 - 8
frameworks/CSharp/genhttp/Benchmarks/Benchmarks.csproj

@@ -16,22 +16,21 @@
     </PropertyGroup>
     </PropertyGroup>
 
 
     <ItemGroup>
     <ItemGroup>
-        <None Remove="Resources\Fortunes.html"/>
-        <None Remove="Resources\Template.html"/>
+        <None Remove="Resources\Fortunes.html" />
+        <None Remove="Resources\Template.html" />
     </ItemGroup>
     </ItemGroup>
 
 
     <ItemGroup>
     <ItemGroup>
-        <EmbeddedResource Include="Resources\Template.html"/>
+        <EmbeddedResource Include="Resources\Template.html" />
     </ItemGroup>
     </ItemGroup>
 
 
     <ItemGroup>
     <ItemGroup>
 
 
-        <PackageReference Include="GenHTTP.Core.Kestrel" Version="9.0.0" />
-        <PackageReference Include="GenHTTP.Modules.Razor" Version="8.6.0" />
-        <PackageReference Include="GenHTTP.Modules.Webservices" Version="9.0.0" />
+        <PackageReference Include="GenHTTP.Core" Version="9.6.2" />
+        <PackageReference Include="GenHTTP.Modules.Webservices" Version="9.6.2" />
 
 
-        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0" />
-        <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.0" />
+        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.1" />
+        <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.3" />
 
 
     </ItemGroup>
     </ItemGroup>
 
 

+ 4 - 2
frameworks/CSharp/genhttp/Benchmarks/Program.cs

@@ -1,14 +1,16 @@
 using Benchmarks.Tests;
 using Benchmarks.Tests;
 using Benchmarks.Utilities;
 using Benchmarks.Utilities;
-using GenHTTP.Engine.Kestrel;
+
+using GenHTTP.Engine.Internal;
+
 using GenHTTP.Modules.IO;
 using GenHTTP.Modules.IO;
 using GenHTTP.Modules.Layouting;
 using GenHTTP.Modules.Layouting;
 using GenHTTP.Modules.Webservices;
 using GenHTTP.Modules.Webservices;
 
 
 var tests = Layout.Create()
 var tests = Layout.Create()
                   .Add("plaintext", Content.From(Resource.FromString("Hello, World!")))
                   .Add("plaintext", Content.From(Resource.FromString("Hello, World!")))
+                  .Add("json", new JsonHandler())
                   .Add("fortunes", new FortuneHandler())
                   .Add("fortunes", new FortuneHandler())
-                  .AddService<JsonResource>("json")
                   .AddService<DbResource>("db")
                   .AddService<DbResource>("db")
                   .AddService<QueryResource>("queries")
                   .AddService<QueryResource>("queries")
                   .AddService<UpdateResource>("updates")
                   .AddService<UpdateResource>("updates")

+ 39 - 0
frameworks/CSharp/genhttp/Benchmarks/Tests/JsonHandler.cs

@@ -0,0 +1,39 @@
+using System.Text.Json;
+
+using GenHTTP.Api.Content;
+using GenHTTP.Api.Protocol;
+
+using GenHTTP.Modules.Conversion.Serializers.Json;
+
+namespace Benchmarks.Tests;
+
+public sealed class JsonResult
+{
+
+    public string Message { get; set; }
+}
+
+public sealed class JsonHandler : IHandler
+{
+    private static readonly FlexibleContentType _ContentType = new(ContentType.ApplicationJson, "utf-8");
+
+    private static readonly JsonSerializerOptions _Options = new();
+
+    public ValueTask PrepareAsync() => new();
+
+    public ValueTask<IResponse> HandleAsync(IRequest request)
+    {
+        var result = new JsonResult()
+        {
+            Message = "Hello, World!"
+        };
+
+        var response = request.Respond()
+                              .Content(new JsonContent(result, _Options))
+                              .Type(_ContentType)
+                              .Build();
+
+        return new(response);
+    }
+
+}

+ 0 - 20
frameworks/CSharp/genhttp/Benchmarks/Tests/JsonResource.cs

@@ -1,20 +0,0 @@
-using GenHTTP.Modules.Webservices;
-
-namespace Benchmarks.Tests;
-
-public sealed class JsonResult
-{
-
-    public string Message { get; set; }
-}
-
-public sealed class JsonResource
-{
-
-    [ResourceMethod]
-    public JsonResult GetMessage() => new()
-    {
-        Message = "Hello, World!"
-    };
-
-}

+ 5 - 0
frameworks/CSharp/genhttp/genhttp.dockerfile

@@ -11,6 +11,11 @@ RUN dotnet publish -c release -o /app -r linux-musl-x64 --no-restore --self-cont
 
 
 # final stage/image
 # final stage/image
 FROM mcr.microsoft.com/dotnet/runtime-deps:9.0-alpine
 FROM mcr.microsoft.com/dotnet/runtime-deps:9.0-alpine
+
+ENV DOTNET_GCDynamicAdaptationMode=0
+ENV DOTNET_ReadyToRun=0
+ENV DOTNET_HillClimbing_Disable=1
+
 WORKDIR /app
 WORKDIR /app
 COPY --from=build /app .
 COPY --from=build /app .
 
 

+ 2 - 4
frameworks/CSharp/sisk/benchmark_config.json

@@ -17,9 +17,7 @@
                 "os": "Linux",
                 "os": "Linux",
                 "database_os": "Linux",
                 "database_os": "Linux",
                 "display_name": "Sisk Framework"
                 "display_name": "Sisk Framework"
-            }
-        },
-        {
+            },
             "cadente": {
             "cadente": {
                 "plaintext_url": "/plaintext",
                 "plaintext_url": "/plaintext",
                 "json_url": "/json",
                 "json_url": "/json",
@@ -38,4 +36,4 @@
             }
             }
         }
         }
     ]
     ]
-}
+}

+ 1 - 1
frameworks/CSharp/sisk/config.toml

@@ -25,4 +25,4 @@ os = "Linux"
 orm = "Raw"
 orm = "Raw"
 platform = ".NET"
 platform = ".NET"
 webserver = "Cadente"
 webserver = "Cadente"
-versus = "None"
+versus = "None"

+ 7 - 3
frameworks/CSharp/sisk/sisk-cadente.dockerfile

@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
 WORKDIR /source
 WORKDIR /source
 
 
 # copy csproj and restore as distinct layers
 # copy csproj and restore as distinct layers
@@ -7,10 +7,14 @@ RUN dotnet restore -r linux-musl-x64
 
 
 # copy and publish app and libraries
 # copy and publish app and libraries
 COPY sisk-cadente/ .
 COPY sisk-cadente/ .
-RUN dotnet publish -c release -o /app -r linux-musl-x64
+RUN dotnet publish -c release -o /app
+
+ENV DOTNET_GCDynamicAdaptationMode=0
+ENV DOTNET_ReadyToRun=0
+ENV DOTNET_HillClimbing_Disable=1
 
 
 # final stage/image
 # final stage/image
-FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime
 WORKDIR /app
 WORKDIR /app
 COPY --from=build /app .
 COPY --from=build /app .
 
 

+ 22 - 14
frameworks/CSharp/sisk/sisk-cadente/Program.cs

@@ -1,10 +1,19 @@
-using System.Text;
+using System.Net;
+using System.Text;
 using System.Text.Json;
 using System.Text.Json;
 using Sisk.Cadente;
 using Sisk.Cadente;
 
 
-var host = new HttpHost ( 8080, session => {
-    var request = session.Request;
+HttpHost.QueueSize = 4096;
+
+var host = new HttpHost ( new IPEndPoint ( IPAddress.Any, 8080 ) );
+host.ContextCreated += Host_ContextCreated;
+
+host.Start ();
+Thread.Sleep ( Timeout.Infinite );
 
 
+void Host_ContextCreated ( HttpHost sender, HttpHostContext session ) {
+    var request = session.Request;
+    
     if (request.Path == "/plaintext") {
     if (request.Path == "/plaintext") {
         SerializePlainTextResponse ( session.Response );
         SerializePlainTextResponse ( session.Response );
     }
     }
@@ -14,23 +23,22 @@ var host = new HttpHost ( 8080, session => {
     else {
     else {
         session.Response.StatusCode = 404;
         session.Response.StatusCode = 404;
     }
     }
-} );
+}
 
 
-host.Start ();
-Thread.Sleep ( Timeout.Infinite );
+static void SerializePlainTextResponse ( HttpHostContext.HttpResponse response ) {
 
 
-static void SerializePlainTextResponse ( HttpResponse response ) {
-    var contentBytes = Encoding.UTF8.GetBytes ( "Hello, world!" );
+    var messageBytes = Encoding.UTF8.GetBytes ( "Hello, World!" );
 
 
-    response.Headers.Add ( new HttpHeader ( "Content-Type", "text/plain" ) );
-    response.ResponseStream = new MemoryStream ( contentBytes );
+    response.Headers.Add ( new HttpHeader ( "Content-Type", "text/plain; charset=UTF-8" ) );
+    response.ResponseStream = new MemoryStream ( messageBytes );
 }
 }
 
 
-static void SerializeJsonResponse ( HttpResponse response ) {
+static void SerializeJsonResponse ( HttpHostContext.HttpResponse response ) {
+
     var contentBytes = JsonSerializer.SerializeToUtf8Bytes ( new {
     var contentBytes = JsonSerializer.SerializeToUtf8Bytes ( new {
-        message = "Hello, world!"
+        message = "Hello, World!"
     } );
     } );
-
-    response.Headers.Add ( new HttpHeader ( "Content-Type", "application/json; charset=utf-8" ) );
+    
+    response.Headers.Add ( new HttpHeader ( "Content-Type", "application/json" ) );
     response.ResponseStream = new MemoryStream ( contentBytes );
     response.ResponseStream = new MemoryStream ( contentBytes );
 }
 }

+ 11 - 11
frameworks/CSharp/sisk/sisk-cadente/sisk.csproj

@@ -1,15 +1,15 @@
 <Project Sdk="Microsoft.NET.Sdk">
 <Project Sdk="Microsoft.NET.Sdk">
 
 
-	<PropertyGroup>
-		<OutputType>Exe</OutputType>
-		<TargetFramework>net8.0</TargetFramework>
-		<ImplicitUsings>enable</ImplicitUsings>
-		<Nullable>enable</Nullable>
-		<ServerGarbageCollection>true</ServerGarbageCollection>
-	</PropertyGroup>
+    <PropertyGroup>
+        <OutputType>Exe</OutputType>
+        <TargetFramework>net9.0</TargetFramework>
+        <ImplicitUsings>enable</ImplicitUsings>
+        <Nullable>enable</Nullable>
+        <ServerGarbageCollection>true</ServerGarbageCollection>
+    </PropertyGroup>
 
 
-	<ItemGroup>
-	  <PackageReference Include="Sisk.Cadente" Version="0.1.42-alpha1" />
-	</ItemGroup>
+    <ItemGroup>
+        <PackageReference Include="Sisk.Cadente" Version="0.1.64-alpha4" />
+    </ItemGroup>
 
 
-</Project>
+</Project>

+ 6 - 2
frameworks/CSharp/sisk/sisk/Program.cs

@@ -1,9 +1,13 @@
 using System.Net.Http.Json;
 using System.Net.Http.Json;
+using System.Text;
 using Sisk.Core.Http;
 using Sisk.Core.Http;
 using Sisk.Core.Routing;
 using Sisk.Core.Routing;
 
 
 var app = HttpServer.CreateBuilder ( host => {
 var app = HttpServer.CreateBuilder ( host => {
     host.UseListeningPort ( "http://+:8080/" );
     host.UseListeningPort ( "http://+:8080/" );
+    host.UseConfiguration ( config => {
+        config.AccessLogsStream = null;
+    } );
 } ).Build ();
 } ).Build ();
 
 
 app.Router.SetRoute ( RouteMethod.Get, "/plaintext", PlainText );
 app.Router.SetRoute ( RouteMethod.Get, "/plaintext", PlainText );
@@ -12,11 +16,11 @@ app.Router.SetRoute ( RouteMethod.Get, "/json", Json );
 app.Start ();
 app.Start ();
 
 
 static HttpResponse PlainText ( HttpRequest request ) {
 static HttpResponse PlainText ( HttpRequest request ) {
-    return new HttpResponse ( "Hello, world!" );
+    return new HttpResponse ( new StringContent ( "Hello, World!", Encoding.UTF8, "text/plain" ) );
 }
 }
 
 
 static HttpResponse Json ( HttpRequest request ) {
 static HttpResponse Json ( HttpRequest request ) {
     return new HttpResponse ( JsonContent.Create ( new {
     return new HttpResponse ( JsonContent.Create ( new {
-        message = "Hello, world!"
+        message = "Hello, World!"
     } ) );
     } ) );
 }
 }

+ 5 - 5
frameworks/FSharp/falco/README.md

@@ -1,11 +1,12 @@
 # Falco Tests on Linux
 # Falco Tests on Linux
+
 This includes tests for plaintext, json, and fortunes HTML serialization.
 This includes tests for plaintext, json, and fortunes HTML serialization.
 
 
 ## Infrastructure Software Versions
 ## Infrastructure Software Versions
 
 
 **Language**
 **Language**
 
 
-* F# 6.0
+* F# 6.0 (or greater)
 
 
 **Platforms**
 **Platforms**
 
 
@@ -18,11 +19,10 @@ This includes tests for plaintext, json, and fortunes HTML serialization.
 **Web Stack**
 **Web Stack**
 
 
 * [Falco](https://github.com/pimbrouwers/Falco)
 * [Falco](https://github.com/pimbrouwers/Falco)
-* [Donald](https://github.com/pimbrouwers/Donald)
 * ASP.NET Core
 * ASP.NET Core
 
 
 ## Paths & Source for Tests
 ## Paths & Source for Tests
 
 
-* [Plaintext](src/App/Value.fs): "/plaintext"
-* [JSON serialization](src/App/Value.fs): "/json"
-* [Fortunes using Donald](src/App/Fortune.fs): "/fortunes"
+* [Plaintext](src/App/Program.fs): "/plaintext"
+* [JSON serialization](src/App/Program.fs): "/json"
+* [Fortunes using Donald](src/App/Program.fs): "/fortunes"

+ 1 - 1
frameworks/FSharp/falco/benchmark_config.json

@@ -18,7 +18,7 @@
         "webserver": "Kestrel",
         "webserver": "Kestrel",
         "os": "Linux",
         "os": "Linux",
         "database_os": "Linux",
         "database_os": "Linux",
-        "display_name": "Falco, Donald",
+        "display_name": "Falco",
         "notes": "",
         "notes": "",
         "versus": "aspcore"
         "versus": "aspcore"
       }
       }

+ 4 - 4
frameworks/FSharp/falco/falco.dockerfile

@@ -1,12 +1,12 @@
-FROM mcr.microsoft.com/dotnet/sdk:7.0.100 AS build
+FROM mcr.microsoft.com/dotnet/sdk:9.0.100 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
 
 
-FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime
 # Full PGO
 # Full PGO
-ENV DOTNET_TieredPGO 1 
-ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_TieredPGO 1
+ENV DOTNET_TC_QuickJitForLoops 1
 ENV DOTNET_ReadyToRun 0
 ENV DOTNET_ReadyToRun 0
 
 
 ENV ASPNETCORE_URLS http://+:8080
 ENV ASPNETCORE_URLS http://+:8080

+ 3 - 8
frameworks/FSharp/falco/src/App/App.fsproj

@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk.Web">
 <Project Sdk="Microsoft.NET.Sdk.Web">
 
 
   <PropertyGroup>
   <PropertyGroup>
-    <TargetFramework>net7.0</TargetFramework>
+    <TargetFramework>net9.0</TargetFramework>
     <DebugType>portable</DebugType>
     <DebugType>portable</DebugType>
     <AssemblyName>App</AssemblyName>
     <AssemblyName>App</AssemblyName>
     <OutputType>Exe</OutputType>
     <OutputType>Exe</OutputType>
@@ -11,17 +11,12 @@
   </PropertyGroup>
   </PropertyGroup>
 
 
   <ItemGroup>
   <ItemGroup>
-    <Compile Include="UI.fs" />
-    <Compile Include="Fortune.fs" />
-    <Compile Include="Server.fs" />
     <Compile Include="Program.fs" />
     <Compile Include="Program.fs" />
   </ItemGroup>
   </ItemGroup>
 
 
   <ItemGroup>
   <ItemGroup>
-    <PackageReference Update="FSharp.Core" Version="7.0.0" />
-    <PackageReference Include="Donald" Version="3.0.*" />
-    <PackageReference Include="Falco" Version="2.0.*" />
-    <PackageReference Include="Npgsql" Version="8.0.3" />
+    <PackageReference Include="Falco" Version="5.*" />
+    <PackageReference Include="Npgsql" Version="9.*" />
   </ItemGroup>
   </ItemGroup>
 
 
 </Project>
 </Project>

+ 0 - 83
frameworks/FSharp/falco/src/App/Fortune.fs

@@ -1,83 +0,0 @@
-module App.Fortune    
-
-open System.Data
-open System.Threading.Tasks     
-open Donald
-open Falco
- 
-type FortuneModel = 
-   {
-       id      : int
-       message : string
-   }
-
-module FortuneModel =
-   let fromDataReader (rd : IDataReader) =
-       {
-           id = rd.GetInt32("id")
-           message = rd.GetString("message")
-       }
-
-module Service = 
-    module ListQuery =              
-        type LoadFortunes = unit -> Task<FortuneModel list>
-
-        let extraFortune = 
-            {
-                id = 0
-                message = "Additional fortune added at request time."
-            }
-
-        let handle
-            (loadFortunes : LoadFortunes) =
-            fun () -> 
-                task {
-                    let! fortunes = loadFortunes ()
-                    
-                    return 
-                        extraFortune 
-                        :: fortunes
-                        |> List.sortBy (fun f -> f.message)
-                }
-
-
-module Db =    
-    let selectAsync (connection : IDbConnection) : Task<FortuneModel list> =        
-        queryAsync 
-            "SELECT id, message FROM fortune"
-            []
-            FortuneModel.fromDataReader
-            connection
-
-module View =
-    open Falco.Markup
-    
-    let index (fortunes : FortuneModel list) =            
-        UI.layout "Fortunes" [
-                Elem.table [] [
-                        yield Elem.tr [] [
-                                Elem.th [] [ Text.raw "id" ]
-                                Elem.th [] [ Text.raw "message" ]
-                            ]
-                        for fortune in fortunes ->
-                            Elem.tr [] [
-                                    Elem.td [] [ Text.raw (string fortune.id) ]
-                                    Elem.td [] [ Text.enc fortune.message]
-                                ]
-                    ]
-            ]
-
-let handleIndex : HttpHandler =        
-    fun ctx ->
-        task {
-            let connFactory = ctx.GetService<DbConnectionFactory>()
-            use conn = createConn connFactory
-            let selectFortunes = fun () -> Db.selectAsync conn
-            let! fortunes = () |> Service.ListQuery.handle selectFortunes
-
-            return!
-                ctx
-                |> (fortunes 
-                    |> View.index 
-                    |> Response.ofHtml)                    
-        } :> Task

+ 86 - 11
frameworks/FSharp/falco/src/App/Program.fs

@@ -1,7 +1,12 @@
 module Program
 module Program
 
 
+open System.Data
 open Falco
 open Falco
-open App
+open Falco.Markup
+open Falco.Routing
+open Microsoft.AspNetCore.Builder
+open Microsoft.Extensions.Logging
+open Npgsql
 
 
 [<Literal>]
 [<Literal>]
 let connectionString = "Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;SSL Mode=Disable;Maximum Pool Size=1024;NoResetOnClose=true;Enlist=false;Max Auto Prepare=4;Multiplexing=true;Write Coalescing Buffer Threshold Bytes=1000"
 let connectionString = "Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;SSL Mode=Disable;Maximum Pool Size=1024;NoResetOnClose=true;Enlist=false;Max Auto Prepare=4;Multiplexing=true;Write Coalescing Buffer Threshold Bytes=1000"
@@ -9,16 +14,86 @@ let connectionString = "Server=tfb-database;Database=hello_world;User Id=benchma
 [<Literal>]
 [<Literal>]
 let defaultMsg = "Hello, World!"
 let defaultMsg = "Hello, World!"
 
 
-type JsonModel = { message : string }
+type JsonResponse =
+    { message : string }
+
+type Fortune =
+    { id : int
+      message : string }
+
+    static member Default =
+        { id = 0
+          message = "Additional fortune added at request time." }
+
+let handleFortunes (connStr : string) : HttpHandler = fun ctx -> task {
+    use conn = new NpgsqlConnection(connStr)
+
+    use comd = conn.CreateCommand()
+    comd.CommandText <- "SELECT id, message FROM fortune"
+
+    do! conn.OpenAsync()
+    use! redr = comd.ExecuteReaderAsync(CommandBehavior.SequentialAccess)
+
+    let! dbFortunes =
+        task {
+            let mutable shouldContinue = true
+            let fortunes = ResizeArray<Fortune>()
+
+            while shouldContinue do
+                let! fortunesRead = redr.ReadAsync()
+
+                if not fortunesRead then
+                    shouldContinue <- false
+                else
+                    fortunes.Add { id = redr.GetInt32(0)
+                                   message = redr.GetString(1) }
+            return fortunes |> List.ofSeq
+        }
+
+    redr.Dispose()
+    comd.Dispose()
+    conn.Dispose()
+
+    let sortedFortunes =
+        Fortune.Default ::
+        dbFortunes
+        |> List.sortBy (fun f -> f.message)
+
+    let html =
+        Elem.html [] [
+            Elem.head [] [
+                    Elem.title [] [ Text.raw "Fortunes" ]
+                ]
+            Elem.body [] [
+                Elem.table [] [
+                        yield Elem.tr [] [
+                                Elem.th [] [ Text.raw "id" ]
+                                Elem.th [] [ Text.raw "message" ]
+                            ]
+                        for fortune in sortedFortunes ->
+                            Elem.tr [] [
+                                    Elem.td [] [ Text.raw (string fortune.id) ]
+                                    Elem.td [] [ Text.enc fortune.message]
+                                ]
+                    ]
+            ]
+        ]
+
+    return Response.ofHtml html ctx
+}
 
 
 [<EntryPoint>]
 [<EntryPoint>]
-let main args =        
-    Host.startWebHost 
-        args        
-        (Server.configure connectionString)
-        [
-            get "/plaintext"  (Response.ofPlainText defaultMsg)
-            get "/json"       (Response.ofJson { message = defaultMsg })
-            get "/fortunes"   Fortune.handleIndex
-        ]    
+let main args =
+    let bldr  = WebApplication.CreateBuilder(args)
+    bldr.Logging.ClearProviders() |> ignore
+
+    let wapp = bldr.Build()
+
+    wapp.UseRouting()
+        .UseFalco([
+            get "/plaintext" (Response.ofPlainText defaultMsg)
+            get "/json" (Response.ofJson { message = defaultMsg })
+            get "/fortunes" (handleFortunes connectionString)
+        ])
+        .Run()
     0
     0

+ 0 - 47
frameworks/FSharp/falco/src/App/Server.fs

@@ -1,47 +0,0 @@
-module App.Server
-
-open System.Data
-open Donald
-open Falco
-open Falco.Host
-open Microsoft.AspNetCore.Builder
-open Microsoft.AspNetCore.Hosting
-open Microsoft.Extensions.DependencyInjection
-open Microsoft.Extensions.Logging
-open Npgsql
-
-type ConnectionString = string
-type ConfigureLogging = ILoggingBuilder -> unit
-type ConfigureServices = DbConnectionFactory -> IServiceCollection -> unit
-type ConfigureApp = HttpEndpoint list -> IApplicationBuilder -> unit
-type ConfigureServer = ConnectionString -> ConfigureWebHost
-
-let configure : ConfigureServer =
-    let configureLogging : ConfigureLogging =
-        fun log ->
-            log.ClearProviders()
-            |> ignore
-
-    let configureServices : ConfigureServices =
-        fun connectionFactory services ->
-            services
-                .AddRouting() 
-                .AddSingleton<DbConnectionFactory>(connectionFactory)
-            |> ignore
-
-    let configure : ConfigureApp =         
-        fun endpoints app ->
-            app.UseRouting()
-               .UseHttpEndPoints(endpoints)       
-               |> ignore 
-
-    fun connectionString endpoints webHost ->    
-        let connectionFactory =     
-            fun () -> new NpgsqlConnection(connectionString) :> IDbConnection
-    
-        webHost
-            .UseKestrel()
-            .ConfigureLogging(configureLogging)
-            .ConfigureServices(configureServices connectionFactory)
-            .Configure(configure endpoints)
-            |> ignore

+ 0 - 11
frameworks/FSharp/falco/src/App/UI.fs

@@ -1,11 +0,0 @@
-module App.UI
-
-open Falco.Markup
-    
-let layout pageTitle content = 
-    Elem.html [] [
-        Elem.head [] [                
-                Elem.title [] [ Text.raw pageTitle ]                                                                
-            ]
-        Elem.body [] content
-    ] 

+ 78 - 0
frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/PgClientConnection.java

@@ -0,0 +1,78 @@
+
+package io.helidon.benchmark.nima.models;
+
+import io.vertx.pgclient.PgConnection;
+import io.vertx.sqlclient.PreparedQuery;
+import io.vertx.sqlclient.Row;
+import io.vertx.sqlclient.RowSet;
+
+public class PgClientConnection implements AutoCloseable {
+    static final int UPDATE_QUERIES = 500;
+    private static String SELECT_WORLD = "SELECT id, randomnumber from WORLD where id=$1";
+    private static String SELECT_FORTUNE = "SELECT * from FORTUNE";
+
+    private PreparedQuery<RowSet<Row>> worldQuery;
+    private PreparedQuery<RowSet<Row>> fortuneQuery;
+    private PreparedQuery<RowSet<Row>>[] updateQuery;
+
+    private final PgConnection conn;
+
+    PgClientConnection(PgConnection conn) {
+        this.conn = conn;
+    }
+
+    public PgConnection pgConnection() {
+        return conn;
+    }
+
+    @Override
+    public void close() {
+        conn.close();
+    }
+
+    public PreparedQuery<RowSet<Row>> worldQuery() {
+        return worldQuery;
+    }
+
+    public PreparedQuery<RowSet<Row>> fortuneQuery() {
+        return fortuneQuery;
+    }
+
+    public PreparedQuery<RowSet<Row>> updateQuery(int queryCount) {
+        return updateQuery[queryCount - 1];
+    }
+
+    @SuppressWarnings("unchecked")
+    void prepare() {
+        try {
+            worldQuery = conn.prepare(SELECT_WORLD)
+                    .toCompletionStage().toCompletableFuture().get().query();
+            fortuneQuery = conn.prepare(SELECT_FORTUNE)
+                    .toCompletionStage().toCompletableFuture().get().query();
+            updateQuery = (PreparedQuery<RowSet<Row>>[]) new PreparedQuery<?>[UPDATE_QUERIES];
+            for (int i = 0; i < UPDATE_QUERIES; i++) {
+                updateQuery[i] = conn.prepare(singleUpdate(i + 1))
+                        .toCompletionStage().toCompletableFuture().get().query();
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static String singleUpdate(int count) {
+        StringBuilder sql = new StringBuilder();
+        sql.append("UPDATE WORLD SET RANDOMNUMBER = CASE ID");
+        for (int i = 0; i < count; i++) {
+            int k = i * 2 + 1;
+            sql.append(" WHEN $").append(k).append(" THEN $").append(k + 1);
+        }
+        sql.append(" ELSE RANDOMNUMBER");
+        sql.append(" END WHERE ID IN ($1");
+        for (int i = 1; i < count; i++) {
+            int k = i * 2 + 1;
+            sql.append(",$").append(k);
+        }
+        sql.append(")");
+        return sql.toString();
+    }
+}

+ 11 - 116
frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/PgClientConnectionPool.java

@@ -1,59 +1,30 @@
 
 
 package io.helidon.benchmark.nima.models;
 package io.helidon.benchmark.nima.models;
 
 
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.locks.ReentrantLock;
-
+import io.helidon.config.Config;
 import io.vertx.core.Vertx;
 import io.vertx.core.Vertx;
 import io.vertx.pgclient.PgConnectOptions;
 import io.vertx.pgclient.PgConnectOptions;
 import io.vertx.pgclient.PgConnection;
 import io.vertx.pgclient.PgConnection;
-import io.vertx.sqlclient.PreparedQuery;
-import io.vertx.sqlclient.Row;
-import io.vertx.sqlclient.RowSet;
 
 
-class PgClientConnectionPool implements AutoCloseable {
+abstract class PgClientConnectionPool implements AutoCloseable {
 
 
+    private final Config config;
     private final Vertx vertx;
     private final Vertx vertx;
     private final PgConnectOptions options;
     private final PgConnectOptions options;
-    private final ReentrantLock lock = new ReentrantLock();
-    private final Map<String, PgClientConnection> connectionMap = new HashMap<>();
 
 
-    public PgClientConnectionPool(Vertx vertx, PgConnectOptions options) {
+    static PgClientConnectionPool create(Vertx vertx, PgConnectOptions options, Config config) {
+        return new PgClientConnectionPoolArray(vertx, options, config);
+    }
+
+    PgClientConnectionPool(Vertx vertx, PgConnectOptions options, Config config) {
         this.vertx = vertx;
         this.vertx = vertx;
         this.options = options;
         this.options = options;
+        this.config = config;
     }
     }
 
 
-    public PgClientConnection clientConnection() {
-        String carrierThread = carrierThread();
-        PgClientConnection connection = connectionMap.get(carrierThread);
-        if (connection == null) {
-            try {
-                lock.lock();
-                connection = connectionMap.get(carrierThread);
-                if (connection == null) {
-                    connection = newConnection();
-                    connectionMap.put(carrierThread, connection);
-                }
-            } finally {
-                lock.unlock();
-            }
-        }
-        return connection;
-    }
+    abstract PgClientConnection clientConnection();
 
 
-    @Override
-    public void close() {
-        try {
-            for (PgClientConnection connection : connectionMap.values()) {
-                connection.close();
-            }
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private PgClientConnection newConnection() {
+    protected PgClientConnection newConnection() {
         try {
         try {
             PgConnection conn = PgConnection.connect(vertx, options)
             PgConnection conn = PgConnection.connect(vertx, options)
                     .toCompletionStage().toCompletableFuture().get();
                     .toCompletionStage().toCompletableFuture().get();
@@ -64,80 +35,4 @@ class PgClientConnectionPool implements AutoCloseable {
             throw new RuntimeException(e);
             throw new RuntimeException(e);
         }
         }
     }
     }
-
-    static String carrierThread() {
-        String threadName = Thread.currentThread().toString();
-        return threadName.substring(threadName.indexOf('@') + 1);
-    }
-
-    public static class PgClientConnection implements AutoCloseable {
-        static final int UPDATE_QUERIES = 500;
-        private static String SELECT_WORLD = "SELECT id, randomnumber from WORLD where id=$1";
-        private static String SELECT_FORTUNE = "SELECT * from FORTUNE";
-
-        private PreparedQuery<RowSet<Row>> worldQuery;
-        private PreparedQuery<RowSet<Row>> fortuneQuery;
-        private PreparedQuery<RowSet<Row>>[] updateQuery;
-
-        private final PgConnection conn;
-
-        PgClientConnection(PgConnection conn) {
-            this.conn = conn;
-        }
-
-        public PgConnection pgConnection() {
-            return conn;
-        }
-
-        @Override
-        public void close() {
-            conn.close();
-        }
-
-        public PreparedQuery<RowSet<Row>> worldQuery() {
-            return worldQuery;
-        }
-
-        public PreparedQuery<RowSet<Row>> fortuneQuery() {
-            return fortuneQuery;
-        }
-
-        public PreparedQuery<RowSet<Row>> updateQuery(int queryCount) {
-            return updateQuery[queryCount - 1];
-        }
-
-        @SuppressWarnings("unchecked")
-        void prepare() {
-            try {
-                worldQuery = conn.prepare(SELECT_WORLD)
-                        .toCompletionStage().toCompletableFuture().get().query();
-                fortuneQuery = conn.prepare(SELECT_FORTUNE)
-                        .toCompletionStage().toCompletableFuture().get().query();
-                updateQuery = (PreparedQuery<RowSet<Row>>[]) new PreparedQuery<?>[UPDATE_QUERIES];
-                for (int i = 0; i < UPDATE_QUERIES; i++) {
-                    updateQuery[i] = conn.prepare(singleUpdate(i + 1))
-                            .toCompletionStage().toCompletableFuture().get().query();
-                }
-            } catch (Exception e) {
-                throw new RuntimeException(e);
-            }
-        }
-
-        private static String singleUpdate(int count) {
-            StringBuilder sql = new StringBuilder();
-            sql.append("UPDATE WORLD SET RANDOMNUMBER = CASE ID");
-            for (int i = 0; i < count; i++) {
-                int k = i * 2 + 1;
-                sql.append(" WHEN $").append(k).append(" THEN $").append(k + 1);
-            }
-            sql.append(" ELSE RANDOMNUMBER");
-            sql.append(" END WHERE ID IN ($1");
-            for (int i = 1; i < count; i++) {
-                int k = i * 2 + 1;
-                sql.append(",$").append(k);
-            }
-            sql.append(")");
-            return sql.toString();
-        }
-    }
 }
 }

+ 60 - 0
frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/PgClientConnectionPoolArray.java

@@ -0,0 +1,60 @@
+
+package io.helidon.benchmark.nima.models;
+
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.logging.Logger;
+
+import io.helidon.config.Config;
+import io.vertx.core.Vertx;
+import io.vertx.pgclient.PgConnectOptions;
+
+class PgClientConnectionPoolArray extends PgClientConnectionPool {
+    private static final Logger LOGGER = Logger.getLogger(PgClientConnectionPoolArray.class.getName());
+
+    private final int connections;
+    private final PgClientConnection[] connectionArray;
+    private final ReentrantLock lock = new ReentrantLock();
+
+    PgClientConnectionPoolArray(Vertx vertx, PgConnectOptions options, Config config) {
+        super(vertx, options, config);
+        double sizeFactor = config.get("pgclient-connection-pool.size-factor")
+                .asDouble()
+                .orElse(1.0);
+        connections = (int) (Runtime.getRuntime().availableProcessors() * sizeFactor);
+        connectionArray = new PgClientConnection[connections];
+        LOGGER.info("Connection pool is " + getClass().getSimpleName());
+        LOGGER.info("Size of connection pool is " + connections);
+    }
+
+    @Override
+    public PgClientConnection clientConnection() {
+        int index = Thread.currentThread().hashCode() % connections;
+        PgClientConnection connection = connectionArray[index];
+        if (connection == null) {
+            try {
+                lock.lock();
+                connection = connectionArray[index];
+                if (connection == null) {
+                    connection = newConnection();
+                    connectionArray[index] = connection;
+                }
+            } finally {
+                lock.unlock();
+            }
+        }
+        return connection;
+    }
+
+    @Override
+    public void close() {
+        try {
+            for (PgClientConnection connection : connectionArray) {
+                if (connection != null) {
+                    connection.close();
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

+ 2 - 5
frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/PgClientRepository.java

@@ -2,7 +2,6 @@ package io.helidon.benchmark.nima.models;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
-import java.util.logging.Logger;
 
 
 import io.helidon.config.Config;
 import io.helidon.config.Config;
 import io.vertx.core.Future;
 import io.vertx.core.Future;
@@ -15,14 +14,12 @@ import io.vertx.sqlclient.RowSet;
 import io.vertx.sqlclient.Tuple;
 import io.vertx.sqlclient.Tuple;
 
 
 import static io.helidon.benchmark.nima.models.DbRepository.randomWorldNumber;
 import static io.helidon.benchmark.nima.models.DbRepository.randomWorldNumber;
-import static io.helidon.benchmark.nima.models.PgClientConnectionPool.PgClientConnection.UPDATE_QUERIES;
+import static io.helidon.benchmark.nima.models.PgClientConnection.UPDATE_QUERIES;
 
 
 public class PgClientRepository implements DbRepository {
 public class PgClientRepository implements DbRepository {
-    private static final Logger LOGGER = Logger.getLogger(PgClientRepository.class.getName());
 
 
     private final PgClientConnectionPool connectionPool;
     private final PgClientConnectionPool connectionPool;
 
 
-    @SuppressWarnings("unchecked")
     public PgClientRepository(Config config) {
     public PgClientRepository(Config config) {
         VertxOptions vertxOptions = new VertxOptions()
         VertxOptions vertxOptions = new VertxOptions()
                 .setPreferNativeTransport(true)
                 .setPreferNativeTransport(true)
@@ -41,7 +38,7 @@ public class PgClientRepository implements DbRepository {
                 .setTcpQuickAck(true)
                 .setTcpQuickAck(true)
                 .setTcpKeepAlive(true)
                 .setTcpKeepAlive(true)
                 .setPipeliningLimit(100000);
                 .setPipeliningLimit(100000);
-        connectionPool = new PgClientConnectionPool(vertx, connectOptions);
+        connectionPool = PgClientConnectionPool.create(vertx, connectOptions, config);
     }
     }
 
 
     @Override
     @Override

+ 2 - 0
frameworks/Java/helidon/nima/src/main/resources/application.yaml

@@ -37,4 +37,6 @@ db: "hello_world"
 username: benchmarkdbuser
 username: benchmarkdbuser
 password: benchmarkdbpass
 password: benchmarkdbpass
 db-repository: "pgclient"     # "pgclient" (default) or "hikari"
 db-repository: "pgclient"     # "pgclient" (default) or "hikari"
+pgclient-connection-pool:
+  size-factor: 1.0            # size = available-processors * size-factor
 
 

+ 1 - 1
frameworks/Java/inverno/inverno-postgres.dockerfile

@@ -2,7 +2,7 @@ FROM maven:3.9.9-eclipse-temurin-21 as maven
 WORKDIR /inverno
 WORKDIR /inverno
 COPY src src
 COPY src src
 COPY pom.xml pom.xml
 COPY pom.xml pom.xml
-RUN mvn package -q -Pio.inverno.io_uring
+RUN mvn package -q -Pio.inverno.epoll
 
 
 EXPOSE 8080
 EXPOSE 8080
 
 

+ 1 - 1
frameworks/Java/inverno/inverno.dockerfile

@@ -2,7 +2,7 @@ FROM maven:3.9.9-eclipse-temurin-21 as maven
 WORKDIR /inverno
 WORKDIR /inverno
 COPY src src
 COPY src src
 COPY pom.xml pom.xml
 COPY pom.xml pom.xml
-RUN mvn package -q -Pio.inverno.io_uring
+RUN mvn package -q -Pio.inverno.epoll
 
 
 EXPOSE 8080
 EXPOSE 8080
 
 

+ 3 - 3
frameworks/Java/smart-socket/benchmark_config.json

@@ -1,5 +1,5 @@
 {
 {
-  "framework": "smart-socket",
+  "framework": "feat",
   "tests": [
   "tests": [
     {
     {
       "default": {
       "default": {
@@ -17,9 +17,9 @@
         "webserver": "None",
         "webserver": "None",
         "os": "Linux",
         "os": "Linux",
         "database_os": "Linux",
         "database_os": "Linux",
-        "display_name": "smart-socket",
+        "display_name": "feat",
         "notes": "",
         "notes": "",
-        "versus": "smart-socket"
+        "versus": "feat"
       },
       },
       "smart-servlet": {
       "smart-servlet": {
         "json_url": "/json",
         "json_url": "/json",

+ 2 - 2
frameworks/Java/smart-socket/smart-socket-smart-servlet.dockerfile → frameworks/Java/smart-socket/feat-smart-servlet.dockerfile

@@ -2,11 +2,11 @@ FROM maven:3.9.7-amazoncorretto-21 as maven
 WORKDIR /smart-socket
 WORKDIR /smart-socket
 COPY pom.xml pom.xml
 COPY pom.xml pom.xml
 COPY src src
 COPY src src
-RUN mvn compile assembly:single -q
+RUN mvn install -q
 
 
 FROM openjdk:21-jdk-slim
 FROM openjdk:21-jdk-slim
 WORKDIR /smart-socket
 WORKDIR /smart-socket
-COPY --from=maven /smart-socket/target/smart-socket-benchmark-1.0-jar-with-dependencies.jar app.jar
+COPY --from=maven /smart-socket/target/smart-socket-benchmark-1.0.jar app.jar
 
 
 EXPOSE 8080
 EXPOSE 8080
 
 

+ 2 - 2
frameworks/Java/smart-socket/smart-socket.dockerfile → frameworks/Java/smart-socket/feat.dockerfile

@@ -2,11 +2,11 @@ FROM maven:3.9.7-amazoncorretto-21 as maven
 WORKDIR /smart-socket
 WORKDIR /smart-socket
 COPY pom.xml pom.xml
 COPY pom.xml pom.xml
 COPY src src
 COPY src src
-RUN mvn compile assembly:single -q
+RUN mvn install -q
 
 
 FROM openjdk:21-jdk-slim
 FROM openjdk:21-jdk-slim
 WORKDIR /smart-socket
 WORKDIR /smart-socket
-COPY --from=maven /smart-socket/target/smart-socket-benchmark-1.0-jar-with-dependencies.jar app.jar
+COPY --from=maven /smart-socket/target/smart-socket-benchmark-1.0.jar app.jar
 
 
 EXPOSE 8080
 EXPOSE 8080
 
 

+ 24 - 9
frameworks/Java/smart-socket/pom.xml

@@ -17,6 +17,11 @@
     </properties>
     </properties>
 
 
     <dependencies>
     <dependencies>
+        <dependency>
+            <groupId>tech.smartboot.feat</groupId>
+            <artifactId>feat-restful</artifactId>
+            <version>0.5</version>
+        </dependency>
         <dependency>
         <dependency>
             <groupId>io.edap</groupId>
             <groupId>io.edap</groupId>
             <artifactId>edapx-json</artifactId>
             <artifactId>edapx-json</artifactId>
@@ -26,6 +31,12 @@
             <groupId>tech.smartboot.servlet</groupId>
             <groupId>tech.smartboot.servlet</groupId>
             <artifactId>servlet-core</artifactId>
             <artifactId>servlet-core</artifactId>
             <version>${smartservlet.version}</version>
             <version>${smartservlet.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>tech.smartboot.feat</groupId>
+                    <artifactId>feat-restful</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
         </dependency>
         <dependency>
         <dependency>
             <groupId>com.zaxxer</groupId>
             <groupId>com.zaxxer</groupId>
@@ -114,20 +125,24 @@
             </plugin>
             </plugin>
 
 
             <plugin>
             <plugin>
-                <artifactId>maven-assembly-plugin</artifactId>
-                <version>3.1.0</version>
-                <configuration>
-                    <descriptorRefs>
-                        <descriptorRef>jar-with-dependencies</descriptorRef>
-                    </descriptorRefs>
-                </configuration>
+                <artifactId>maven-shade-plugin</artifactId>
+                <version>3.3.0</version>
                 <executions>
                 <executions>
                     <execution>
                     <execution>
-                        <id>make-assembly</id>
                         <phase>package</phase>
                         <phase>package</phase>
                         <goals>
                         <goals>
-                            <goal>single</goal>
+                            <goal>shade</goal>
                         </goals>
                         </goals>
+                        <configuration>
+                            <createDependencyReducedPom>false</createDependencyReducedPom>
+                            <transformers>
+                                <!-- 采用追加的方式 -->
+                                <transformer
+                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/services/tech.smartboot.feat.core.apt.AptLoader</resource>
+                                </transformer>
+                            </transformers>
+                        </configuration>
                     </execution>
                     </execution>
                 </executions>
                 </executions>
             </plugin>
             </plugin>

+ 18 - 17
frameworks/Java/smart-socket/src/main/java/org/smartboot/http/Bootstrap.java

@@ -8,12 +8,7 @@
 
 
 package org.smartboot.http;
 package org.smartboot.http;
 
 
-import org.smartboot.Message;
-import tech.smartboot.feat.core.Feat;
-import tech.smartboot.feat.core.common.enums.HeaderValueEnum;
-import tech.smartboot.feat.core.server.HttpHandler;
-import tech.smartboot.feat.core.server.HttpRequest;
-import tech.smartboot.feat.core.server.HttpResponse;
+import tech.smartboot.feat.restful.RestFeat;
 
 
 public class Bootstrap {
 public class Bootstrap {
     static byte[] body = "Hello, World!".getBytes();
     static byte[] body = "Hello, World!".getBytes();
@@ -21,21 +16,27 @@ public class Bootstrap {
     public static void main(String[] args) {
     public static void main(String[] args) {
         int cpuNum = Runtime.getRuntime().availableProcessors();
         int cpuNum = Runtime.getRuntime().availableProcessors();
         // 定义服务器接受的消息类型以及各类消息对应的处理器
         // 定义服务器接受的消息类型以及各类消息对应的处理器
-        Feat.createHttpServer(options -> {
+//        Feat.createHttpServer(options -> {
+//            options.threadNum(cpuNum + 1)
+//                    .headerLimiter(0)
+//                    .readBufferSize(1024 * 4)
+//                    .writeBufferSize(1024 * 4);
+//        }).httpHandler(request -> {
+//            HttpResponse response = request.getResponse();
+//            if ("/plaintext".equals(request.getRequestURI())) {
+//                response.setContentLength(body.length);
+//                response.setContentType(HeaderValueEnum.ContentType.TEXT_PLAIN_UTF8);
+//                response.write(body);
+//            } else if ("/json".equals(request.getRequestURI())) {
+//                response.setContentType("application/json");
+//                JsonUtil.writeJsonBytes(response, new Message("Hello, World!"));
+//            }
+//        }).listen(8080);
+        RestFeat.createServer(options -> {
             options.threadNum(cpuNum + 1)
             options.threadNum(cpuNum + 1)
                     .headerLimiter(0)
                     .headerLimiter(0)
                     .readBufferSize(1024 * 4)
                     .readBufferSize(1024 * 4)
                     .writeBufferSize(1024 * 4);
                     .writeBufferSize(1024 * 4);
-        }).httpHandler(request -> {
-            HttpResponse response = request.getResponse();
-            if ("/plaintext".equals(request.getRequestURI())) {
-                response.setContentLength(body.length);
-                response.setContentType(HeaderValueEnum.ContentType.TEXT_PLAIN_UTF8);
-                response.write(body);
-            } else if ("/json".equals(request.getRequestURI())) {
-                response.setContentType("application/json");
-                JsonUtil.writeJsonBytes(response, new Message("Hello, World!"));
-            }
         }).listen(8080);
         }).listen(8080);
     }
     }
 
 

+ 24 - 0
frameworks/Java/smart-socket/src/main/java/org/smartboot/http/FeatController.java

@@ -0,0 +1,24 @@
+package org.smartboot.http;
+
+import org.smartboot.Message;
+import tech.smartboot.feat.core.apt.annotation.Controller;
+import tech.smartboot.feat.core.apt.annotation.RequestMapping;
+import tech.smartboot.feat.core.common.enums.HeaderValueEnum;
+import tech.smartboot.feat.core.server.HttpResponse;
+
+@Controller
+public class FeatController {
+    static byte[] body = "Hello, World!".getBytes();
+
+    @RequestMapping("/plaintext")
+    public byte[] plaintext(HttpResponse response) {
+        response.setContentType(HeaderValueEnum.ContentType.TEXT_PLAIN_UTF8);
+        return body;
+    }
+
+    @RequestMapping("/json")
+    public Message json(HttpResponse response) {
+        response.setContentType(HeaderValueEnum.ContentType.APPLICATION_JSON_UTF8);
+        return new Message("Hello, World!");
+    }
+}

+ 19 - 0
frameworks/Java/tio-boot/.dockerignore

@@ -0,0 +1,19 @@
+.github
+.git
+.DS_Store
+docs
+kubernetes
+node_modules
+/.svelte-kit
+/package
+.env
+.env.*
+vite.config.js.timestamp-*
+vite.config.ts.timestamp-*
+__pycache__
+.env
+_old
+uploads
+.ipynb_checkpoints
+**/*.db
+_test

+ 3 - 0
frameworks/Java/tio-boot/.gitignore

@@ -0,0 +1,3 @@
+/target/
+logs
+.settings

+ 114 - 0
frameworks/Java/tio-boot/README.md

@@ -0,0 +1,114 @@
+# t-io Benchmarking Test
+
+This is the tio-server portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
+
+## Controller
+
+These implementations use the tio-server's controller.
+
+### Plaintext Test
+
+* [Plaintext test source](src/main/java/com/litongjava/tio/http/server/controller/IndexController.java)
+
+### JSON Serialization Test
+
+* [JSON test source](src/main/java/com/litongjava/tio/http/server/controller/IndexController.java)
+
+### Database Query Test
+
+* [Database Query test source](src/main/java/com/litongjava/tio/http/server/controller/DbController.java))
+
+### Database Queries Test
+
+* [Database Queries test source](src/main/java/com/litongjava/tio/http/server/controller/DbController.java))
+
+### Database Update Test
+
+* [Database Update test source](src/main/java/com/litongjava/tio/http/server/controller/DbController.java))
+
+### Template rendering Test
+
+* [Template rendering test source](src/main/java/com/litongjava/tio/http/server/controller/DbController.java))
+
+### Cache Query Test
+* [Cache query test source](src/main/java/com/litongjava/tio/http/server/controller/CacheController.java))
+
+
+## Versions
+3.7.3.v20231218-RELEASE (https://gitee.com/litongjava/t-io)
+
+## Test URLs
+
+All implementations use the same URLs.
+
+### Plaintext Test
+
+    http://localhost:8080/plaintext
+
+### JSON Encoding Test
+
+    http://localhost:8080/json
+
+### Database Query Test
+
+    http://localhost:8080/db
+
+### Database Queries Test
+
+    http://localhost:8080/queries?queries=5
+
+### Cache Query Test
+
+    http://localhost:8080/cacheQuery?queries=10000
+
+### Template rendering Test
+
+    http://localhost:8080/fortunes
+    
+### Database Update Test
+
+    http://localhost:8080/updates?queries=5
+
+ ## Hot to run
+ ### install mysql 8
+ - 1.please instal mysql 8.0.32,example cmd
+ ```
+ docker run --restart=always -d --name mysql_8 --hostname mysql \
+-p 3306:3306 \
+-e 'MYSQL_ROOT_PASSWORD=robot_123456#' -e 'MYSQL_ROOT_HOST=%' -e 'MYSQL_DATABASE=hello_world' \
+mysql/mysql-server:8.0.32 \
+--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --lower_case_table_names=1
+ ```
+ - 2.create database schema hello_world
+ - 3.create tablle,[example](sql/hello_world.sql)
+ - 4.import data
+ 
+ ### docker 
+ ```
+ docker build -t tio-server-benchmark -f tio-server.dockerfile .
+```
+The run is to specify the mysql database
+```
+docker run --rm -p 8080:8080 \
+-e JDBC_URL="jdbc:mysql://192.168.3.9/hello_world" \
+-e JDBC_USER="root" \
+-e JDBC_PSWD="robot_123456#" \
+tio-server-benchmark
+```
+
+### windows
+
+-windows
+```
+D:\java\jdk1.8.0_121\bin\java -jar target\tio-server-benchmark-1.0.jar --JDBC_URL=jdbc:mysql://192.168.3.9/hello_world?useSSL=false --JDBC_USER=root --JDBC_PSWD=robot_123456#
+```
+or 
+```
+set JDBC_URL=jdbc:mysql://192.168.3.9/hello_world
+set jdbc.user=root
+set JDBC_PSWD=robot_123456#
+D:\java\jdk1.8.0_121\bin\java -jar target\tio-server-benchmark-1.0.jar
+```
+
+
+

+ 227 - 0
frameworks/Java/tio-boot/api/tio-server-benchmark.md

@@ -0,0 +1,227 @@
+---
+title: tio-server-benchmark v1.0.0
+language_tabs:
+  - shell: Shell
+  - http: HTTP
+  - javascript: JavaScript
+  - ruby: Ruby
+  - python: Python
+  - php: PHP
+  - java: Java
+  - go: Go
+toc_footers: []
+includes: []
+search: true
+code_clipboard: true
+highlight_theme: darkula
+headingLevel: 2
+generator: "@tarslib/widdershins v4.0.17"
+
+---
+
+# tio-server-benchmark
+
+> v1.0.0
+
+Base URLs:
+
+# Authentication
+
+# Default
+
+## GET plaintext
+
+GET /plaintext
+
+> 返回示例
+
+> 200 Response
+
+```json
+{}
+```
+
+### 返回结果
+
+|状态码|状态码含义|说明|数据模型|
+|---|---|---|---|
+|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|成功|Inline|
+
+### 返回数据结构
+
+## GET json
+
+GET /json
+
+> 返回示例
+
+> 200 Response
+
+```json
+{}
+```
+
+### 返回结果
+
+|状态码|状态码含义|说明|数据模型|
+|---|---|---|---|
+|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|成功|Inline|
+
+### 返回数据结构
+
+## GET db
+
+GET /db
+
+### 请求参数
+
+|名称|位置|类型|必选|说明|
+|---|---|---|---|---|
+|id|query|string| 否 |none|
+
+> 返回示例
+
+> 200 Response
+
+```json
+{
+  "id": 0,
+  "randomNumber": 0
+}
+```
+
+### 返回结果
+
+|状态码|状态码含义|说明|数据模型|
+|---|---|---|---|
+|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|成功|Inline|
+
+### 返回数据结构
+
+状态码 **200**
+
+|名称|类型|必选|约束|中文名|说明|
+|---|---|---|---|---|---|
+|» id|integer|true|none||none|
+|» randomNumber|integer|true|none||none|
+
+## GET updates
+
+GET /updates
+
+### 请求参数
+
+|名称|位置|类型|必选|说明|
+|---|---|---|---|---|
+|queries|query|string| 否 |none|
+
+> 返回示例
+
+> 成功
+
+```json
+[
+  {
+    "id": 28,
+    "randomNumber": 5399,
+    "randomnumber": 1498
+  }
+]
+```
+
+### 返回结果
+
+|状态码|状态码含义|说明|数据模型|
+|---|---|---|---|
+|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|成功|Inline|
+
+### 返回数据结构
+
+状态码 **200**
+
+|名称|类型|必选|约束|中文名|说明|
+|---|---|---|---|---|---|
+|» id|integer|false|none||none|
+|» randomNumber|integer|false|none||none|
+|» randomnumber|integer|false|none||none|
+
+## GET fortunes
+
+GET /fortunes
+
+> 返回示例
+
+> 200 Response
+
+```json
+{}
+```
+
+### 返回结果
+
+|状态码|状态码含义|说明|数据模型|
+|---|---|---|---|
+|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|成功|Inline|
+
+### 返回数据结构
+
+## GET cacheQuery
+
+GET /cacheQuery
+
+### 请求参数
+
+|名称|位置|类型|必选|说明|
+|---|---|---|---|---|
+|queries|query|string| 否 |none|
+
+> 返回示例
+
+> 200 Response
+
+```json
+[
+  {
+    "id": 0,
+    "randomNumber": 0
+  }
+]
+```
+
+### 返回结果
+
+|状态码|状态码含义|说明|数据模型|
+|---|---|---|---|
+|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|成功|Inline|
+
+### 返回数据结构
+
+状态码 **200**
+
+|名称|类型|必选|约束|中文名|说明|
+|---|---|---|---|---|---|
+|» id|integer|false|none||none|
+|» randomNumber|integer|false|none||none|
+
+## GET cacheList
+
+GET /cacheList
+
+> 返回示例
+
+> 200 Response
+
+```json
+{}
+```
+
+### 返回结果
+
+|状态码|状态码含义|说明|数据模型|
+|---|---|---|---|
+|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|成功|Inline|
+
+### 返回数据结构
+
+# 数据模型
+

+ 29 - 0
frameworks/Java/tio-boot/benchmark_config.json

@@ -0,0 +1,29 @@
+{
+  "framework": "tio-boot",
+  "tests": [{
+    "default": {
+      "plaintext_url": "/plaintext",
+      "json_url": "/json",
+      "db_url": "/db",
+      "query_url": "/queries?queries=",
+      "fortune_url": "/fortunes",
+      "update_url": "/updates?queries=",
+      "cached_query_url" : "/cachedQuery?queries=",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Micro",
+      "database": "MySQL",
+      "framework": "tio-boot",
+      "language": "Java",
+      "flavor": "None",
+      "orm": "Raw",
+      "platform": "t-io",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "tio-boot",
+      "notes": "tio-boot",
+      "versus": "t-io"
+    }
+  }]
+}

+ 19 - 0
frameworks/Java/tio-boot/config.toml

@@ -0,0 +1,19 @@
+[framework]
+name = "t-io"
+
+[main]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+urls.query = "/queries?queries="
+urls.update = "/updates?queries="
+urls.fortune = "/fortunes"
+urls.cached_query = "/cachedQuery?queries="
+approach = "Realistic"
+classification = "Micro"
+database = "None"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "t-io"
+webserver = "None"
+versus = "t-io"

+ 126 - 0
frameworks/Java/tio-boot/pom.xml

@@ -0,0 +1,126 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.litongjava</groupId>
+  <artifactId>tio-boot-benchmark</artifactId>
+  <version>1.0</version>
+  <name>${project.artifactId}</name>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <java.version>1.8</java.version>
+    <maven.compiler.source>${java.version}</maven.compiler.source>
+    <maven.compiler.target>${java.version}</maven.compiler.target>
+    <tio-boot.version>1.9.1</tio-boot.version>
+
+    <main.class>com.litongjava.tio.http.server.MainApp</main.class>
+  </properties>
+  <dependencies>
+    <!-- Tio Boot 框架 -->
+    <dependency>
+      <groupId>com.litongjava</groupId>
+      <artifactId>tio-boot</artifactId>
+      <version>${tio-boot.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.litongjava</groupId>
+      <artifactId>java-db</artifactId>
+      <version>1.4.9</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.12</version>
+      <scope>test</scope>
+    </dependency>
+
+
+    <dependency>
+      <groupId>com.alibaba.fastjson2</groupId>
+      <artifactId>fastjson2</artifactId>
+      <version>2.0.52</version>
+    </dependency>
+
+    <dependency>
+      <groupId>net.sf.ehcache</groupId>
+      <artifactId>ehcache-core</artifactId>
+      <version>2.6.11</version>
+    </dependency>
+
+    <dependency>
+      <groupId>mysql</groupId>
+      <artifactId>mysql-connector-java</artifactId>
+      <version>5.1.46</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.zaxxer</groupId>
+      <artifactId>HikariCP</artifactId>
+      <version>4.0.3</version>
+    </dependency>
+
+  </dependencies>
+  <repositories>
+    <repository>
+      <id>central</id>
+      <name>Central Repository</name>
+      <url>https://repo.maven.apache.org/maven2</url>
+    </repository>
+    <repository>
+      <id>sonatype-nexus-snapshots</id>
+      <name>Sonatype Nexus Snapshots</name>
+      <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+    </repository>
+  </repositories>
+  <pluginRepositories>
+    <pluginRepository>
+      <id>central</id>
+      <name>Central Repository</name>
+      <url>https://repo.maven.apache.org/maven2</url>
+    </pluginRepository>
+    <pluginRepository>
+      <id>sonatype-nexus-snapshots</id>
+      <name>Sonatype Nexus Snapshots</name>
+      <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+      <releases>
+        <enabled>false</enabled>
+      </releases>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
+    </pluginRepository>
+  </pluginRepositories>
+  <build>
+    <plugins>
+
+      <plugin>
+        <inherited>true</inherited>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.8.0</version>
+        <configuration>
+          <debug>false</debug>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <version>3.1.0</version>
+        <configuration>
+          <descriptorRefs>
+            <descriptorRef>jar-with-dependencies</descriptorRef>
+          </descriptorRefs>
+        </configuration>
+        <executions>
+          <execution>
+            <id>make-assembly</id>
+            <phase>package</phase>
+            <goals>
+              <goal>single</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>

+ 13 - 0
frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/MainApp.java

@@ -0,0 +1,13 @@
+package com.litongjava.tio.http.server;
+
+import com.litongjava.tio.boot.TioApplication;
+
+public class MainApp {
+
+  public static void main(String[] args) {
+    long start = System.currentTimeMillis();
+    TioApplication.run(MainApp.class, new MainAppConfig(), args);
+    long end = System.currentTimeMillis();
+    System.out.println((end - start) + "ms");
+  }
+}

+ 54 - 0
frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/MainAppConfig.java

@@ -0,0 +1,54 @@
+package com.litongjava.tio.http.server;
+
+import com.litongjava.context.BootConfiguration;
+import com.litongjava.tio.boot.server.TioBootServer;
+import com.litongjava.tio.http.server.config.EhCachePluginConfig;
+import com.litongjava.tio.http.server.config.EnjoyEngineConfig;
+import com.litongjava.tio.http.server.config.MysqlDbConfig;
+import com.litongjava.tio.http.server.controller.CacheHandler;
+import com.litongjava.tio.http.server.controller.DbHandler;
+import com.litongjava.tio.http.server.controller.IndexHandler;
+import com.litongjava.tio.http.server.router.HttpRequestRouter;
+import com.litongjava.tio.utils.environment.EnvUtils;
+
+public class MainAppConfig implements BootConfiguration {
+
+  @Override
+  public void config() throws Exception {
+    // add route
+    IndexHandler controller = new IndexHandler();
+
+    TioBootServer server = TioBootServer.me();
+    HttpRequestRouter requestRouter = server.getRequestRouter();
+
+    requestRouter.add("/", controller::index);
+    requestRouter.add("/plaintext", controller::plaintext);
+    requestRouter.add("/json", controller::json);
+
+    DbHandler dbQueryController = new DbHandler();
+    requestRouter.add("/db", dbQueryController::db);
+    requestRouter.add("/queries", dbQueryController::queries);
+    requestRouter.add("/updates", dbQueryController::updates);
+    requestRouter.add("/fortunes", dbQueryController::fortunes);
+
+    CacheHandler cacheController = new CacheHandler();
+    requestRouter.add("/cachedQuery", cacheController::cachedQuery);
+
+    boolean db = EnvUtils.getBoolean("db", true);
+    if (db) {
+      try {
+        new MysqlDbConfig().init();
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+    // start enjoy and ehcache
+    try {
+      new EnjoyEngineConfig().engine();
+      new EhCachePluginConfig().ehCachePlugin();
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+}

+ 12 - 0
frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/config/EhCachePluginConfig.java

@@ -0,0 +1,12 @@
+  package com.litongjava.tio.http.server.config;
+
+import com.litongjava.ehcache.EhCachePlugin;
+
+public class EhCachePluginConfig {
+
+  public EhCachePlugin ehCachePlugin() {
+    EhCachePlugin ehCachePlugin = new EhCachePlugin();
+    ehCachePlugin.start();
+    return ehCachePlugin;
+  }
+}

+ 22 - 0
frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/config/EnjoyEngineConfig.java

@@ -0,0 +1,22 @@
+package com.litongjava.tio.http.server.config;
+
+import com.jfinal.template.Engine;
+
+public class EnjoyEngineConfig {
+
+  private final String RESOURCE_BASE_PATH = "/templates/";
+
+  public Engine engine() {
+    Engine engine = Engine.use();
+    engine.setBaseTemplatePath(RESOURCE_BASE_PATH);
+    engine.setToClassPathSourceFactory();
+    // 支持模板热加载,绝大多数生产环境下也建议配置成 true,除非是极端高性能的场景
+    // engine.setDevMode(true);
+    // 配置极速模式,性能提升 13%
+    Engine.setFastMode(true);
+    // jfinal 4.9.02 新增配置:支持中文表达式、中文变量名、中文方法名、中文模板函数名
+    Engine.setChineseExpression(true);
+    return engine;
+  }
+
+}

+ 31 - 0
frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/config/MysqlDbConfig.java

@@ -0,0 +1,31 @@
+package com.litongjava.tio.http.server.config;
+
+import com.litongjava.db.activerecord.ActiveRecordPlugin;
+import com.litongjava.db.activerecord.OrderedFieldContainerFactory;
+import com.litongjava.db.hikaricp.HikariCpPlugin;
+import com.litongjava.tio.utils.environment.EnvUtils;
+
+public class MysqlDbConfig {
+
+  public void init() {
+    // start active recored
+    String jdbcUrl = EnvUtils.get("JDBC_URL");
+    // String jdbcUrl = "jdbc:mysql://192.168.3.9/hello_world";
+
+    String jdbcUser = EnvUtils.get("JDBC_USER");
+    // String jdbcUser = "root";
+
+    String jdbcPswd = EnvUtils.get("JDBC_PSWD");
+    // String jdbcPswd = "robot_123456#";
+    HikariCpPlugin hikariCpPlugin = new HikariCpPlugin(jdbcUrl, jdbcUser, jdbcPswd);
+
+    ActiveRecordPlugin arp = new ActiveRecordPlugin(hikariCpPlugin);
+    arp.setContainerFactory(new OrderedFieldContainerFactory());
+
+    // arp.setShowSql(true);
+
+    hikariCpPlugin.start();
+    boolean start = arp.start();
+    System.out.println("db started:" + start);
+  }
+}

+ 41 - 0
frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/controller/CacheHandler.java

@@ -0,0 +1,41 @@
+package com.litongjava.tio.http.server.controller;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import com.alibaba.fastjson2.JSON;
+import com.litongjava.db.activerecord.Db;
+import com.litongjava.db.activerecord.Row;
+import com.litongjava.tio.http.common.HeaderName;
+import com.litongjava.tio.http.common.HeaderValue;
+import com.litongjava.tio.http.common.HttpRequest;
+import com.litongjava.tio.http.common.HttpResponse;
+import com.litongjava.tio.http.server.utils.RandomUtils;
+
+public class CacheHandler {
+  // private Logger log = LoggerFactory.getLogger(this.getClass());
+
+  public HttpResponse cachedQuery(HttpRequest request) {
+    String queries = request.getParam("queries");
+    List<Map<String, Object>> recordMaps = RandomUtils.randomWorldNumbers()
+        // limit
+        .limit(RandomUtils.parseQueryCount(queries)) // 限制查询数量
+        .mapToObj(id -> findByIdWithCache("world", id)) // 使用 mapToObj 将 int 映射为对象
+        .filter(Objects::nonNull) // 过滤掉 null 值
+        .map(Row::toMap) // 将每个 Record 对象转换为 Map
+        .collect(Collectors.toList()); // 收集到 List
+
+    HttpResponse httpResponse = new HttpResponse(request);
+    httpResponse.addHeader(HeaderName.Content_Type, HeaderValue.Content_Type.TEXT_PLAIN_JSON);
+    httpResponse.setBody(JSON.toJSONBytes(recordMaps));
+    return httpResponse;
+
+  }
+
+  private Row findByIdWithCache(String tableName, int id) {
+    String sql = "SELECT id, randomNumber FROM world WHERE id = ?";
+    return Db.findFirstByCache(tableName, id, sql, id);
+  }
+}

+ 126 - 0
frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/controller/DbHandler.java

@@ -0,0 +1,126 @@
+package com.litongjava.tio.http.server.controller;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import com.alibaba.fastjson2.JSON;
+import com.jfinal.template.Engine;
+import com.jfinal.template.Template;
+import com.litongjava.db.activerecord.Db;
+import com.litongjava.db.activerecord.Row;
+import com.litongjava.ehcache.EhCacheKit;
+import com.litongjava.tio.http.common.HeaderName;
+import com.litongjava.tio.http.common.HeaderValue;
+import com.litongjava.tio.http.common.HttpRequest;
+import com.litongjava.tio.http.common.HttpResponse;
+import com.litongjava.tio.http.server.model.Fortune;
+import com.litongjava.tio.http.server.util.Resps;
+import com.litongjava.tio.http.server.utils.RandomUtils;
+
+public class DbHandler {
+
+  public HttpResponse db(HttpRequest request) {
+    Integer id = request.getInt("id");
+    if (id == null) {
+      id = RandomUtils.randomWorldNumber();
+    }
+
+    //System.out.println("id:" + id);
+    HttpResponse httpResponse = new HttpResponse(request);
+
+    // int id = 11;
+    // String sql="SELECT id, randomNumber FROM world WHERE id = ?";
+
+    Row recored = Db.findById("world", id);
+    if (recored != null) {
+      httpResponse.setBody(JSON.toJSONBytes(recored.toMap()));
+    } else {
+      httpResponse.setBody("{}".getBytes());
+    }
+
+    httpResponse.addHeader(HeaderName.Content_Type, HeaderValue.Content_Type.TEXT_PLAIN_JSON);
+
+    return httpResponse;
+  }
+
+  // @GetMapping("/queries")
+  public HttpResponse queries(HttpRequest request) {
+    String queries = request.getParam("queries");
+    List<Map<String, Object>> recordMaps = RandomUtils.randomWorldNumbers()
+        // limit
+        .limit(RandomUtils.parseQueryCount(queries)) // 限制查询数量
+        .mapToObj(id -> Db.findById("world", id)) // 使用 mapToObj 将 int 映射为对象
+        .filter(Objects::nonNull) // 过滤掉 null 值
+        .map(Row::toMap) // 将每个 Record 对象转换为 Map
+        .collect(Collectors.toList()); // 收集到 List
+
+    HttpResponse httpResponse = new HttpResponse(request);
+    httpResponse.addHeader(HeaderName.Content_Type, HeaderValue.Content_Type.TEXT_PLAIN_JSON);
+    httpResponse.setBody(JSON.toJSONBytes(recordMaps));
+    return httpResponse;
+  }
+
+  //@GetMapping("/updates")
+  public HttpResponse updates(HttpRequest request) {
+    String queries = request.getParam("queries");
+
+    EhCacheKit.removeAll("world");
+
+    List<Map<String, Object>> updatedRecords = RandomUtils.randomWorldNumbers()// random numbers
+        // limit
+        .limit(RandomUtils.parseQueryCount(queries))
+        // map
+        .mapToObj(id -> Db.findById("world", id))
+        // not null
+        .filter(Objects::nonNull).map(record -> {
+          int currentRandomNumber = record.getInt("randomNumber"); // "randomnumber"
+          int newRandomNumber;
+          do {
+            newRandomNumber = RandomUtils.randomWorldNumber();
+          } while (newRandomNumber == currentRandomNumber);
+
+          record.set("randomnumber", newRandomNumber);
+          Db.update("world", "id", record); // update
+          return record;
+        })
+        // tomap
+        .map(Row::toMap)
+        // to List
+        .collect(Collectors.toList());
+
+    HttpResponse httpResponse = new HttpResponse(request);
+    httpResponse.addHeader(HeaderName.Content_Type, HeaderValue.Content_Type.TEXT_PLAIN_JSON);
+    httpResponse.setBody(JSON.toJSONBytes(updatedRecords));
+    return httpResponse;
+  }
+
+  public HttpResponse fortunes(HttpRequest request) throws IllegalAccessException, InstantiationException {
+    List<Row> records = Db.find("SELECT * FROM fortune");
+
+    List<Fortune> fortunes = new ArrayList<>(records.size());
+    for (Row record : records) {
+      fortunes.add(record.toBean(Fortune.class));
+    }
+    // 添加额外的 Fortune
+    fortunes.add(new Fortune(0L, "Additional fortune added at request time."));
+
+    // 按照消息排序
+    fortunes.sort(Comparator.comparing(Fortune::getMessage));
+
+    Map<String, Object> viewData = new HashMap<>();
+    viewData.put("fortunes", fortunes);
+
+    // 转换为 HTML
+    Engine engine = Engine.use();
+    String filename = "fortunes.html";
+    Template template = engine.getTemplate(filename);
+    String html = template.renderToString(viewData);
+
+    return Resps.html(request, html);
+  }
+}

+ 40 - 0
frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/controller/IndexHandler.java

@@ -0,0 +1,40 @@
+package com.litongjava.tio.http.server.controller;
+
+import com.alibaba.fastjson2.JSON;
+import com.litongjava.tio.http.common.HeaderName;
+import com.litongjava.tio.http.common.HeaderValue;
+import com.litongjava.tio.http.common.HttpRequest;
+import com.litongjava.tio.http.common.HttpResponse;
+import com.litongjava.tio.http.server.model.Message;
+import com.litongjava.tio.http.server.util.Resps;
+
+/**
+ * ab -k -n1000000 -c10 http://127.0.0.1:8080/json 
+ * ab -k -n1000000 -c10 http://127.0.0.1:8080/plaintext
+ */
+public class IndexHandler {
+  private static final String HELLO_WORLD = "Hello, World!";
+
+  private static final byte[] HELLO_WORLD_BYTES = HELLO_WORLD.getBytes();
+
+  public HttpResponse index(HttpRequest request) {
+    return Resps.txt(request, "tio-boot");
+  }
+
+  public HttpResponse plaintext(HttpRequest request) {
+    // 更高性能的写法
+    HttpResponse ret = new HttpResponse(request);
+    ret.setBody(HELLO_WORLD_BYTES);
+    ret.addHeader(HeaderName.Content_Type, HeaderValue.Content_Type.TEXT_PLAIN_TXT);
+    return ret;
+  }
+
+  // 在IndexController中添加
+  public HttpResponse json(HttpRequest request) {
+    // 更高性能的写法
+    HttpResponse ret = new HttpResponse(request);
+    ret.setBody(JSON.toJSONString(new Message(HELLO_WORLD)).getBytes());
+    ret.addHeader(HeaderName.Content_Type, HeaderValue.Content_Type.TEXT_PLAIN_JSON);
+    return ret;
+  }
+}

+ 23 - 0
frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/model/Fortune.java

@@ -0,0 +1,23 @@
+package com.litongjava.tio.http.server.model;
+
+public final class Fortune {
+
+  public Long id;
+  public String message;
+
+  public Fortune() {
+  }
+
+  public Fortune(Long id, String message) {
+    this.id = id;
+    this.message = message;
+  }
+
+  public Long getId() {
+    return id;
+  }
+
+  public String getMessage() {
+    return message;
+  }
+}

+ 12 - 0
frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/model/Message.java

@@ -0,0 +1,12 @@
+package com.litongjava.tio.http.server.model;
+public final class Message {
+	private final String message;
+
+	public Message(String message) {
+		this.message = message;
+	}
+
+	public String getMessage() {
+		return message;
+	}
+}

+ 32 - 0
frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/model/World.java

@@ -0,0 +1,32 @@
+package com.litongjava.tio.http.server.model;
+
+public final class World {
+
+  public int id;
+  public int randomnumber;
+
+  protected World() {
+  }
+
+  public World(int id, int randomnumber) {
+    this.id = id;
+    this.randomnumber = randomnumber;
+  }
+
+  public int getId() {
+    return id;
+  }
+
+  public void setId(int id) {
+    this.id = id;
+  }
+
+  public int getRandomnumber() {
+    return randomnumber;
+  }
+
+  public void setRandomnumber(int randomnumber) {
+    this.randomnumber = randomnumber;
+  }
+
+}

+ 50 - 0
frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/services/CacheName.java

@@ -0,0 +1,50 @@
+package com.litongjava.tio.http.server.services;
+
+public class CacheName {
+  // `cacheName`(缓存名称)
+  private String name;
+  // `timeToLiveSeconds`(生存时间)和`timeToIdleSeconds`(闲置时间)。
+  private Long timeToLiveSeconds;
+  private Long timeToIdleSeconds;
+
+  public CacheName() {
+  }
+
+  public CacheName(String name, Long timeToLiveSeconds, Long timeToIdleSeconds) {
+    super();
+    this.name = name;
+    this.timeToLiveSeconds = timeToLiveSeconds;
+    this.timeToIdleSeconds = timeToIdleSeconds;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public Long getTimeToLiveSeconds() {
+    return timeToLiveSeconds;
+  }
+
+  public void setTimeToLiveSeconds(Long timeToLiveSeconds) {
+    this.timeToLiveSeconds = timeToLiveSeconds;
+  }
+
+  public Long getTimeToIdleSeconds() {
+    return timeToIdleSeconds;
+  }
+
+  public void setTimeToIdleSeconds(Long timeToIdleSeconds) {
+    this.timeToIdleSeconds = timeToIdleSeconds;
+  }
+
+  @Override
+  public String toString() {
+    return "CacheName [name=" + name + ", timeToLiveSeconds=" + timeToLiveSeconds + ", timeToIdleSeconds="
+        + timeToIdleSeconds + "]";
+  }
+
+}

+ 17 - 0
frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/services/CacheNameService.java

@@ -0,0 +1,17 @@
+package com.litongjava.tio.http.server.services;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.litongjava.model.time.Time;
+
+public class CacheNameService {
+  private CacheName demo = new CacheName("world", null, Time.MINUTE_1 * 10);
+
+  public List<CacheName> cacheNames() {
+    List<CacheName> list = new ArrayList<>();
+    list.add(demo);
+    return list;
+  }
+
+}

+ 36 - 0
frameworks/Java/tio-boot/src/main/java/com/litongjava/tio/http/server/utils/RandomUtils.java

@@ -0,0 +1,36 @@
+package com.litongjava.tio.http.server.utils;
+
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.stream.IntStream;
+
+public class RandomUtils {
+
+  private static final int MIN_WORLD_NUMBER = 1;
+  private static final int MAX_WORLD_NUMBER_PLUS_ONE = 10_001;
+//  private static final int MAX_WORLD_NUMBER_PLUS_ONE = 30;
+
+  public static int randomWorldNumber() {
+    return ThreadLocalRandom.current().nextInt(MIN_WORLD_NUMBER, MAX_WORLD_NUMBER_PLUS_ONE);
+  }
+
+  public static IntStream randomWorldNumbers() {
+    return ThreadLocalRandom.current().ints(MIN_WORLD_NUMBER, MAX_WORLD_NUMBER_PLUS_ONE)
+        // distinct() allows us to avoid using Hibernate's first-level cache in
+        // the JPA-based implementation. Using a cache like that would bypass
+        // querying the database, which would violate the test requirements.
+        .distinct();
+  }
+
+  public static int parseQueryCount(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));
+  }
+}

+ 9 - 0
frameworks/Java/tio-boot/src/main/resources/app.properties

@@ -0,0 +1,9 @@
+http.response.header.showServer=true
+server.port=8080
+#JDBC_URL=jdbc:mysql://192.168.3.9/hello_world?useSSL=false&allowPublicKeyRetrieval=true
+#JDBC_USER=root
+#JDBC_PSWD=robot_123456#
+
+JDBC_URL=jdbc:mysql://tfb-database/hello_world
+JDBC_USER=benchmarkdbuser
+JDBC_PSWD=benchmarkdbpass

+ 9 - 0
frameworks/Java/tio-boot/src/main/resources/ehcache.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false">
+
+  <diskStore path="java.io.tmpdir/EhCache" />
+
+  <defaultCache eternal="false" maxElementsInMemory="10000" overflowToDisk="false" diskPersistent="false"
+                timeToIdleSeconds="1800" timeToLiveSeconds="259200" memoryStoreEvictionPolicy="LRU" />
+</ehcache>

+ 52 - 0
frameworks/Java/tio-boot/src/main/resources/logback.xml

@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<configuration>
+  <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径 -->
+  <property name="LOG_HOME" value="logs" />
+  <!--格式化输出:%d表示日期,%-6level:日志级别从左显示6个字符宽度,%m:日志消息,%n是换行符 -->
+  <property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-6level%logger{0}.%M:%L - %m%n" />
+
+  <!-- 控制台输出 -->
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+      <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+    </encoder>
+  </appender>
+
+  <!-- 按照每天生成日志文件 -->
+  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+      <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+    </encoder>
+    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+      <!--日志文件输出的文件名 -->
+      <fileNamePattern>${LOG_HOME}/project-name-%d{yyyy-MM-dd}.log</fileNamePattern>
+      <!--日志文件保留天数 -->
+      <maxHistory>180</maxHistory>
+    </rollingPolicy>
+    <!--日志文件最大的大小 -->
+    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>10MB</maxFileSize>
+    </triggeringPolicy>
+  </appender>
+  
+  <!--专为 spring 定制 -->
+  <logger name="org.springframework" level="info" />
+  <!-- show parameters for hibernate sql 专为 Hibernate 定制 -->
+  <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" />
+  <logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" />
+  <logger name="org.hibernate.SQL" level="DEBUG" />
+  <logger name="org.hibernate.engine.QueryParameters" level="DEBUG" />
+  <logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" />
+
+  <!--myibatis log configure -->
+  <logger name="com.apache.ibatis" level="TRACE" />
+  <logger name="java.sql.Connection" level="DEBUG" />
+  <logger name="java.sql.Statement" level="DEBUG" />
+  <logger name="java.sql.PreparedStatement" level="DEBUG" />
+
+  <!-- 日志输出级别 和输出源 -->
+  <root level="info">
+    <appender-ref ref="STDOUT" />
+    <appender-ref ref="FILE" />
+  </root>
+</configuration>

+ 20 - 0
frameworks/Java/tio-boot/src/main/resources/templates/fortunes.html

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Fortunes</title>
+</head>
+<body>
+<table>
+  <tr>
+    <th>id</th>
+    <th>message</th>
+  </tr>
+  #for(fortune : fortunes)
+  <tr>
+    <td>#(fortune.id)</td>
+    <td>#escape(fortune.message)</td>
+  </tr>
+  #end
+</table>
+</body>
+</html>

+ 15 - 0
frameworks/Java/tio-boot/src/test/java/com/litongjava/tio/http/server/MainAppTest.java

@@ -0,0 +1,15 @@
+package com.litongjava.tio.http.server;
+
+import org.junit.Test;
+
+import com.litongjava.tio.utils.environment.EnvUtils;
+
+public class MainAppTest {
+
+  @Test
+  public void test() {
+    boolean boolean1 = EnvUtils.getBoolean("native", false);
+    System.out.println(boolean1);
+  }
+
+}

+ 20 - 0
frameworks/Java/tio-boot/tio-boot.dockerfile

@@ -0,0 +1,20 @@
+FROM litongjava/maven:3.8.8-jdk8u391 AS builder
+WORKDIR /app
+
+COPY pom.xml pom.xml
+RUN mvn dependency:go-offline  -q
+
+COPY src src
+RUN mvn package -Passembly -q
+RUN ls -l && ls -l target
+
+FROM litongjava/jre:8u391-stable-slim
+
+WORKDIR /app
+
+COPY --from=builder /app/target/tio-boot-benchmark-1.0-jar-with-dependencies.jar /app/tio-boot-benchmark-1.0.jar
+
+EXPOSE 8080
+
+# java --server -XX:+UseNUMA XX:+UseParallelGC -cp target/tio-boot-benchmark-1.0-jar-with-dependencies.jar com.litongjava.tio.http.server.MainApp
+CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC","-cp", "/app/tio-boot-benchmark-1.0.jar","com.litongjava.tio.http.server.MainApp"]

+ 64 - 151
frameworks/Java/tio-http-server/pom.xml

@@ -16,12 +16,12 @@
     <dependency>
     <dependency>
       <groupId>com.litongjava</groupId>
       <groupId>com.litongjava</groupId>
       <artifactId>tio-http-server</artifactId>
       <artifactId>tio-http-server</artifactId>
-      <version>3.7.3.v20240919-RELEASE</version>
+      <version>3.7.3.v20250301-RELEASE</version>
     </dependency>
     </dependency>
     <dependency>
     <dependency>
       <groupId>com.litongjava</groupId>
       <groupId>com.litongjava</groupId>
       <artifactId>java-db</artifactId>
       <artifactId>java-db</artifactId>
-      <version>1.2.6</version>
+      <version>1.4.9</version>
     </dependency>
     </dependency>
     <dependency>
     <dependency>
       <groupId>junit</groupId>
       <groupId>junit</groupId>
@@ -31,16 +31,6 @@
     </dependency>
     </dependency>
 
 
 
 
-    <!-- https://mvnrepository.com/artifact/com.jfinal/activerecord -->
-    <!--
-    <dependency>
-      <groupId>com.jfinal</groupId>
-      <artifactId>activerecord</artifactId>
-      <version>5.1.6</version>
-    </dependency>
-    -->
-
-
     <dependency>
     <dependency>
       <groupId>com.alibaba.fastjson2</groupId>
       <groupId>com.alibaba.fastjson2</groupId>
       <artifactId>fastjson2</artifactId>
       <artifactId>fastjson2</artifactId>
@@ -66,144 +56,67 @@
     </dependency>
     </dependency>
 
 
   </dependencies>
   </dependencies>
-  <profiles>
-    <!-- 开发环境 -->
-    <profile>
-      <id>development</id>
-      <activation>
-        <activeByDefault>true</activeByDefault>
-      </activation>
-      <dependencies>
-        <dependency>
-          <groupId>ch.qos.logback</groupId>
-          <artifactId>logback-classic</artifactId>
-          <version>1.2.13</version>
-        </dependency>
-      </dependencies>
-    </profile>
+  <repositories>
+    <repository>
+      <id>central</id>
+      <name>Central Repository</name>
+      <url>https://repo.maven.apache.org/maven2</url>
+    </repository>
+    <repository>
+      <id>sonatype-nexus-snapshots</id>
+      <name>Sonatype Nexus Snapshots</name>
+      <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+    </repository>
+  </repositories>
+  <pluginRepositories>
+    <pluginRepository>
+      <id>central</id>
+      <name>Central Repository</name>
+      <url>https://repo.maven.apache.org/maven2</url>
+    </pluginRepository>
+    <pluginRepository>
+      <id>sonatype-nexus-snapshots</id>
+      <name>Sonatype Nexus Snapshots</name>
+      <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+      <releases>
+        <enabled>false</enabled>
+      </releases>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
+    </pluginRepository>
+  </pluginRepositories>
+  <build>
+    <plugins>
+
+      <plugin>
+        <inherited>true</inherited>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.8.0</version>
+        <configuration>
+          <debug>false</debug>
+        </configuration>
+      </plugin>
 
 
-    <!-- 生产环境 -->
-    <profile>
-      <id>production</id>
-      <dependencies>
-        <dependency>
-          <groupId>ch.qos.logback</groupId>
-          <artifactId>logback-classic</artifactId>
-          <version>1.2.13</version>
-        </dependency>
-      </dependencies>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-maven-plugin</artifactId>
-            <version>2.7.4</version>
-            <configuration>
-              <mainClass>${main.class}</mainClass>
-              <excludeGroupIds>org.projectlombok</excludeGroupIds>
-            </configuration>
-            <!-- 设置执行目标 -->
-            <executions>
-              <execution>
-                <goals>
-                  <goal>repackage</goal>
-                </goals>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-    <!-- assembly -->
-    <profile>
-      <id>assembly</id>
-      <dependencies>
-        <dependency>
-          <groupId>ch.qos.logback</groupId>
-          <artifactId>logback-classic</artifactId>
-          <version>1.2.13</version>
-        </dependency>
-      </dependencies>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-jar-plugin</artifactId>
-            <version>3.2.0</version>
-          </plugin>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-assembly-plugin</artifactId>
-            <version>3.1.1</version>
-            <configuration>
-              <archive>
-                <manifest>
-                  <mainClass>${main.class}</mainClass>
-                </manifest>
-              </archive>
-              <descriptorRefs>
-                <descriptorRef>jar-with-dependencies</descriptorRef>
-              </descriptorRefs>
-              <appendAssemblyId>false</appendAssemblyId>
-            </configuration>
-            <executions>
-              <execution>
-                <id>make-assembly</id>
-                <phase>package</phase>
-                <goals>
-                  <goal>single</goal>
-                </goals>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-    <profile>
-      <id>native</id>
-      <dependencies>
-        <!-- GraalVM 环境使用 jdk log -->
-        <dependency>
-          <groupId>org.slf4j</groupId>
-          <artifactId>slf4j-jdk14</artifactId>
-          <version>1.7.31</version>
-        </dependency>
-        <!-- GraalVM -->
-        <dependency>
-          <groupId>org.graalvm.sdk</groupId>
-          <artifactId>graal-sdk</artifactId>
-          <version>${graalvm.version}</version>
-          <scope>provided</scope>
-        </dependency>
-      </dependencies>
-      <build>
-        <finalName>${project.artifactId}</finalName>
-        <plugins>
-          <plugin>
-            <groupId>org.graalvm.nativeimage</groupId>
-            <artifactId>native-image-maven-plugin</artifactId>
-            <version>21.2.0</version>
-            <executions>
-              <execution>
-                <goals>
-                  <goal>native-image</goal>
-                </goals>
-                <phase>package</phase>
-              </execution>
-            </executions>
-            <configuration>
-              <skip>false</skip>
-              <imageName>${project.artifactId}</imageName>
-              <mainClass>${main.class}</mainClass>
-              <buildArgs>
-                -H:+RemoveSaturatedTypeFlows
-                --allow-incomplete-classpath
-                --no-fallback
-              </buildArgs>
-            </configuration>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <version>3.1.0</version>
+        <configuration>
+          <descriptorRefs>
+            <descriptorRef>jar-with-dependencies</descriptorRef>
+          </descriptorRefs>
+        </configuration>
+        <executions>
+          <execution>
+            <id>make-assembly</id>
+            <phase>package</phase>
+            <goals>
+              <goal>single</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
 </project>
 </project>

+ 11 - 3
frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/MainApp.java

@@ -9,7 +9,7 @@ import com.litongjava.tio.http.server.controller.CacheController;
 import com.litongjava.tio.http.server.controller.DbController;
 import com.litongjava.tio.http.server.controller.DbController;
 import com.litongjava.tio.http.server.controller.IndexController;
 import com.litongjava.tio.http.server.controller.IndexController;
 import com.litongjava.tio.http.server.handler.DefaultHttpRequestDispatcher;
 import com.litongjava.tio.http.server.handler.DefaultHttpRequestDispatcher;
-import com.litongjava.tio.http.server.router.DefaultHttpReqeustRouter;
+import com.litongjava.tio.http.server.router.DefaultHttpRequestRouter;
 import com.litongjava.tio.http.server.router.HttpRequestRouter;
 import com.litongjava.tio.http.server.router.HttpRequestRouter;
 import com.litongjava.tio.server.ServerTioConfig;
 import com.litongjava.tio.server.ServerTioConfig;
 import com.litongjava.tio.utils.environment.EnvUtils;
 import com.litongjava.tio.utils.environment.EnvUtils;
@@ -18,11 +18,12 @@ public class MainApp {
 
 
   public static void main(String[] args) {
   public static void main(String[] args) {
     long start = System.currentTimeMillis();
     long start = System.currentTimeMillis();
+    EnvUtils.buildCmdArgsMap(args);
     EnvUtils.load();
     EnvUtils.load();
     // add route
     // add route
     IndexController controller = new IndexController();
     IndexController controller = new IndexController();
 
 
-    HttpRequestRouter simpleHttpRoutes = new DefaultHttpReqeustRouter();
+    HttpRequestRouter simpleHttpRoutes = new DefaultHttpRequestRouter();
     simpleHttpRoutes.add("/", controller::index);
     simpleHttpRoutes.add("/", controller::index);
     simpleHttpRoutes.add("/plaintext", controller::plaintext);
     simpleHttpRoutes.add("/plaintext", controller::plaintext);
     simpleHttpRoutes.add("/json", controller::json);
     simpleHttpRoutes.add("/json", controller::json);
@@ -49,9 +50,16 @@ public class MainApp {
     // close Heartbeat
     // close Heartbeat
     serverTioConfig.setHeartbeatTimeout(0);
     serverTioConfig.setHeartbeatTimeout(0);
     serverTioConfig.statOn = false;
     serverTioConfig.statOn = false;
+    boolean db = EnvUtils.getBoolean("db", true);
+    if (db) {
+      try {
+        new MysqlDbConfig().init();
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
     // start server
     // start server
     try {
     try {
-      new MysqlDbConfig().init();
       new EnjoyEngineConfig().engine();
       new EnjoyEngineConfig().engine();
       new EhCachePluginConfig().ehCachePlugin();
       new EhCachePluginConfig().ehCachePlugin();
       httpServerStarter.start();
       httpServerStarter.start();

+ 3 - 3
frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/controller/CacheController.java

@@ -7,7 +7,7 @@ import java.util.stream.Collectors;
 
 
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSON;
 import com.litongjava.db.activerecord.Db;
 import com.litongjava.db.activerecord.Db;
-import com.litongjava.db.activerecord.Record;
+import com.litongjava.db.activerecord.Row;
 import com.litongjava.tio.http.common.HeaderName;
 import com.litongjava.tio.http.common.HeaderName;
 import com.litongjava.tio.http.common.HeaderValue;
 import com.litongjava.tio.http.common.HeaderValue;
 import com.litongjava.tio.http.common.HttpRequest;
 import com.litongjava.tio.http.common.HttpRequest;
@@ -24,7 +24,7 @@ public class CacheController {
         .limit(RandomUtils.parseQueryCount(queries)) // 限制查询数量
         .limit(RandomUtils.parseQueryCount(queries)) // 限制查询数量
         .mapToObj(id -> findByIdWithCache("world", id)) // 使用 mapToObj 将 int 映射为对象
         .mapToObj(id -> findByIdWithCache("world", id)) // 使用 mapToObj 将 int 映射为对象
         .filter(Objects::nonNull) // 过滤掉 null 值
         .filter(Objects::nonNull) // 过滤掉 null 值
-        .map(Record::toMap) // 将每个 Record 对象转换为 Map
+        .map(Row::toMap) // 将每个 Record 对象转换为 Map
         .collect(Collectors.toList()); // 收集到 List
         .collect(Collectors.toList()); // 收集到 List
 
 
     HttpResponse httpResponse = new HttpResponse(request);
     HttpResponse httpResponse = new HttpResponse(request);
@@ -34,7 +34,7 @@ public class CacheController {
 
 
   }
   }
 
 
-  private Record findByIdWithCache(String tableName, int id) {
+  private Row findByIdWithCache(String tableName, int id) {
     String sql = "SELECT id, randomNumber FROM world WHERE id = ?";
     String sql = "SELECT id, randomNumber FROM world WHERE id = ?";
     return Db.findFirstByCache(tableName, id, sql, id);
     return Db.findFirstByCache(tableName, id, sql, id);
   }
   }

+ 10 - 11
frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/controller/DbController.java

@@ -12,15 +12,14 @@ import com.alibaba.fastjson2.JSON;
 import com.jfinal.template.Engine;
 import com.jfinal.template.Engine;
 import com.jfinal.template.Template;
 import com.jfinal.template.Template;
 import com.litongjava.db.activerecord.Db;
 import com.litongjava.db.activerecord.Db;
-import com.litongjava.db.activerecord.Record;
-import com.litongjava.ehcache.EhCache;
+import com.litongjava.db.activerecord.Row;
+import com.litongjava.ehcache.EhCacheKit;
 import com.litongjava.tio.http.common.HeaderName;
 import com.litongjava.tio.http.common.HeaderName;
 import com.litongjava.tio.http.common.HeaderValue;
 import com.litongjava.tio.http.common.HeaderValue;
 import com.litongjava.tio.http.common.HttpRequest;
 import com.litongjava.tio.http.common.HttpRequest;
 import com.litongjava.tio.http.common.HttpResponse;
 import com.litongjava.tio.http.common.HttpResponse;
 import com.litongjava.tio.http.server.model.Fortune;
 import com.litongjava.tio.http.server.model.Fortune;
 import com.litongjava.tio.http.server.util.Resps;
 import com.litongjava.tio.http.server.util.Resps;
-import com.litongjava.tio.http.server.utils.BeanConverterUtils;
 import com.litongjava.tio.http.server.utils.RandomUtils;
 import com.litongjava.tio.http.server.utils.RandomUtils;
 
 
 public class DbController {
 public class DbController {
@@ -37,7 +36,7 @@ public class DbController {
     // int id = 11;
     // int id = 11;
     // String sql="SELECT id, randomNumber FROM world WHERE id = ?";
     // String sql="SELECT id, randomNumber FROM world WHERE id = ?";
 
 
-    Record recored = Db.findById("world", id);
+    Row recored = Db.findById("world", id);
     if (recored != null) {
     if (recored != null) {
       httpResponse.setBody(JSON.toJSONBytes(recored.toMap()));
       httpResponse.setBody(JSON.toJSONBytes(recored.toMap()));
     } else {
     } else {
@@ -57,7 +56,7 @@ public class DbController {
         .limit(RandomUtils.parseQueryCount(queries)) // 限制查询数量
         .limit(RandomUtils.parseQueryCount(queries)) // 限制查询数量
         .mapToObj(id -> Db.findById("world", id)) // 使用 mapToObj 将 int 映射为对象
         .mapToObj(id -> Db.findById("world", id)) // 使用 mapToObj 将 int 映射为对象
         .filter(Objects::nonNull) // 过滤掉 null 值
         .filter(Objects::nonNull) // 过滤掉 null 值
-        .map(Record::toMap) // 将每个 Record 对象转换为 Map
+        .map(Row::toMap) // 将每个 Record 对象转换为 Map
         .collect(Collectors.toList()); // 收集到 List
         .collect(Collectors.toList()); // 收集到 List
 
 
     HttpResponse httpResponse = new HttpResponse(request);
     HttpResponse httpResponse = new HttpResponse(request);
@@ -66,11 +65,11 @@ public class DbController {
     return httpResponse;
     return httpResponse;
   }
   }
 
 
-//@GetMapping("/updates")
+  //@GetMapping("/updates")
   public HttpResponse updates(HttpRequest request) {
   public HttpResponse updates(HttpRequest request) {
     String queries = request.getParam("queries");
     String queries = request.getParam("queries");
 
 
-    EhCache.removeAll("world");
+    EhCacheKit.removeAll("world");
 
 
     List<Map<String, Object>> updatedRecords = RandomUtils.randomWorldNumbers()// random numbers
     List<Map<String, Object>> updatedRecords = RandomUtils.randomWorldNumbers()// random numbers
         // limit
         // limit
@@ -90,7 +89,7 @@ public class DbController {
           return record;
           return record;
         })
         })
         // tomap
         // tomap
-        .map(Record::toMap)
+        .map(Row::toMap)
         // to List
         // to List
         .collect(Collectors.toList());
         .collect(Collectors.toList());
 
 
@@ -101,11 +100,11 @@ public class DbController {
   }
   }
 
 
   public HttpResponse fortunes(HttpRequest request) throws IllegalAccessException, InstantiationException {
   public HttpResponse fortunes(HttpRequest request) throws IllegalAccessException, InstantiationException {
-    List<Record> records = Db.find("SELECT * FROM fortune"); 
+    List<Row> records = Db.find("SELECT * FROM fortune");
 
 
     List<Fortune> fortunes = new ArrayList<>(records.size());
     List<Fortune> fortunes = new ArrayList<>(records.size());
-    for (Record record : records) {
-      fortunes.add(BeanConverterUtils.toBean(record.toMap(), Fortune.class));
+    for (Row record : records) {
+      fortunes.add(record.toBean(Fortune.class));
     }
     }
     // 添加额外的 Fortune
     // 添加额外的 Fortune
     fortunes.add(new Fortune(0L, "Additional fortune added at request time."));
     fortunes.add(new Fortune(0L, "Additional fortune added at request time."));

+ 0 - 31
frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/utils/BeanConverterUtils.java

@@ -1,31 +0,0 @@
-package com.litongjava.tio.http.server.utils;
-
-import java.lang.reflect.Field;
-import java.util.Map;
-
-public class BeanConverterUtils {
-
-  /**
-   * Map to to bean 
-   */
-  public static <T> T toBean(Map<String, Object> map, Class<T> beanClass)
-      throws IllegalAccessException, InstantiationException {
-
-    T bean = beanClass.newInstance(); // 创建 Bean 的实例
-
-    for (Field field : beanClass.getDeclaredFields()) {
-      field.setAccessible(true); // 确保私有字段也可以访问
-
-      if (map.containsKey(field.getName())) {
-        Object value = map.get(field.getName());
-
-        // 如果字段类型与值类型兼容,则设置字段的值
-        if (value != null && field.getType().isAssignableFrom(value.getClass())) {
-          field.set(bean, value);
-        }
-      }
-    }
-
-    return bean;
-  }
-}

+ 3 - 2
frameworks/Java/tio-http-server/tio-server.dockerfile

@@ -12,8 +12,9 @@ FROM litongjava/jre:8u391-stable-slim
 
 
 WORKDIR /app
 WORKDIR /app
 
 
-COPY --from=builder /app/target/tio-http-server-benchmark-1.0.jar /app/target/tio-http-server-benchmark-1.0.jar
+COPY --from=builder /app/target/tio-http-server-benchmark-1.0-jar-with-dependencies.jar /app/tio-http-server-benchmark-1.0.jar
 
 
 EXPOSE 8080
 EXPOSE 8080
 
 
-CMD ["java","-jar", "/app/target/tio-http-server-benchmark-1.0.jar"]
+# java --server -XX:+UseNUMA XX:+UseParallelGC -cp target/tio-http-server-benchmark-1.0-jar-with-dependencies.jar com.litongjava.tio.http.server.MainApp
+CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC","-cp", "/app/tio-http-server-benchmark-1.0.jar","com.litongjava.tio.http.server.MainApp"]

+ 27 - 0
frameworks/JavaScript/aroma.js/README.md

@@ -0,0 +1,27 @@
+# Aroma.js Benchmarking Test
+
+From [aroma.js.org](https://aroma.js.org):
+
+> Aroma.js is a lightweight, feature-rich, and developer-friendly web framework designed to build modern web applications with ease. It provides essential features like routing, middleware, session management, cookie handling, template rendering, static file serving, and more. With its simple API, it enables rapid development of web applications with flexibility.
+
+### Test Type Implementation Source Code
+
+- [JSON](app.js)
+- [PLAINTEXT](app.js)
+
+## Important Libraries
+
+The tests were run with:
+
+- [Aroma.js](https://aroma.js.org/)
+- [NodeJS](https://nodejs.org/en/)
+
+## Test URLs
+
+### JSON
+
+http://localhost:8080/json
+
+### PLAINTEXT
+
+http://localhost:8080/plaintext

+ 36 - 0
frameworks/JavaScript/aroma.js/app.js

@@ -0,0 +1,36 @@
+
+const cluster = require('cluster'),
+  numCPUs = require('os').cpus().length,
+  Aroma = require('aroma.js');
+
+
+if (cluster.isPrimary) {
+  console.log(`Primary ${process.pid} is running`);
+
+  for (let i = 0; i < numCPUs; i++) {
+    cluster.fork();
+  }
+
+  cluster.on('exit', (worker, code, signal) => {
+    console.log(`worker ${worker.process.pid} died`);
+  });
+} else {
+  const app = module.exports = new Aroma();
+
+  app.parseUrlEncoded();
+
+   app.use((req, res, next) => {
+    res.setHeader("Server", "Aroma.js");
+    return next();
+  });
+
+  app.get('/json', (req, res) => res.send({ message: 'Hello, World!' }));
+
+  app.get('/plaintext', (req, res) => {
+    res.setHeader('Content-Type', 'text/plain');
+    res.send('Hello, World!');
+  });
+  
+
+  app.listen(8080);
+}

+ 11 - 0
frameworks/JavaScript/aroma.js/aroma.js.dockerfile

@@ -0,0 +1,11 @@
+FROM node:20.16-slim
+
+COPY ./ ./
+
+RUN npm install
+
+ENV NODE_ENV production
+
+EXPOSE 8080
+
+CMD ["node", "app.js"]

+ 21 - 0
frameworks/JavaScript/aroma.js/benchmark_config.json

@@ -0,0 +1,21 @@
+{
+    "framework": "aroma.js",
+    "tests": [{
+      "default": {
+        "json_url": "/json",
+        "plaintext_url": "/plaintext",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "framework": "aroma.js",
+        "language": "JavaScript",
+        "flavor": "NodeJS",
+        "platform": "nodejs",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "aroma.js",
+        "versus": "nodejs"
+      }
+    }]
+  }

+ 13 - 0
frameworks/JavaScript/aroma.js/config.toml

@@ -0,0 +1,13 @@
+[framework]
+name = "aroma.js"
+
+[main]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+approach = "Realistic"
+classification = "Micro"
+database_os = "Linux"
+os = "Linux"
+platform = "nodejs"
+webserver = "None"
+versus = "nodejs"

+ 8 - 0
frameworks/JavaScript/aroma.js/package.json

@@ -0,0 +1,8 @@
+{
+    "name": "aroma.js",
+    "dependencies": {
+      "aroma.js": "1.0.8"
+    },
+    "main": "app.js"
+  }
+  

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

@@ -7,7 +7,7 @@
   "dependencies": {
   "dependencies": {
     "bluebird": "3.5.1",
     "bluebird": "3.5.1",
     "handlebars": "4.3.0",
     "handlebars": "4.3.0",
-    "koa": "2.5.0",
+    "koa": "2.15.4",
     "koa-bodyparser": "4.2.0",
     "koa-bodyparser": "4.2.0",
     "koa-hbs": "1.0.0",
     "koa-hbs": "1.0.0",
     "koa-router": "7.4.0",
     "koa-router": "7.4.0",

+ 4 - 4
frameworks/Kotlin/hexagon/benchmark_config.json

@@ -48,7 +48,7 @@
                 "notes": "http://hexagonkt.com",
                 "notes": "http://hexagonkt.com",
                 "versus": "servlet"
                 "versus": "servlet"
             },
             },
-            "jettyloom": {
+            "jdk": {
                 "json_url": "/json",
                 "json_url": "/json",
                 "db_url": "/db",
                 "db_url": "/db",
                 "query_url": "/query?queries=",
                 "query_url": "/query?queries=",
@@ -67,11 +67,11 @@
                 "webserver": "None",
                 "webserver": "None",
                 "os": "Linux",
                 "os": "Linux",
                 "database_os": "Linux",
                 "database_os": "Linux",
-                "display_name": "Hexagon Jetty Loom PostgreSQL",
+                "display_name": "Hexagon JDK PostgreSQL",
                 "notes": "http://hexagonkt.com",
                 "notes": "http://hexagonkt.com",
                 "versus": "servlet"
                 "versus": "servlet"
             },
             },
-            "jettyloom-pgclient": {
+            "jdk-pgclient": {
                 "json_url": "/json",
                 "json_url": "/json",
                 "db_url": "/db",
                 "db_url": "/db",
                 "query_url": "/query?queries=",
                 "query_url": "/query?queries=",
@@ -90,7 +90,7 @@
                 "webserver": "None",
                 "webserver": "None",
                 "os": "Linux",
                 "os": "Linux",
                 "database_os": "Linux",
                 "database_os": "Linux",
-                "display_name": "Hexagon Jetty Loom PgClient",
+                "display_name": "Hexagon JDK PgClient",
                 "notes": "http://hexagonkt.com",
                 "notes": "http://hexagonkt.com",
                 "versus": "servlet"
                 "versus": "servlet"
             },
             },

+ 10 - 10
frameworks/Kotlin/hexagon/build.gradle

@@ -1,26 +1,26 @@
 
 
 plugins {
 plugins {
-    id "org.jetbrains.kotlin.jvm" version "2.0.21" apply false
-    id "org.graalvm.buildtools.native" version "0.10.4" apply false
+    id "org.jetbrains.kotlin.jvm" version "2.1.0" apply false
+    id "org.graalvm.buildtools.native" version "0.10.5" apply false
 }
 }
 
 
 version = "1.0.0"
 version = "1.0.0"
 description = "TFB benchmark"
 description = "TFB benchmark"
-group = "com.hexagonkt"
+group = "com.hexagontk"
 
 
 ext {
 ext {
-    hexagonVersion = "3.7.3"
+    hexagonVersion = "4.0.1"
     jettyVersion = "12.0.16"
     jettyVersion = "12.0.16"
-    nettyVersion = "4.1.116.Final"
+    nettyVersion = "4.1.118.Final"
 
 
     hikariVersion = "6.2.1"
     hikariVersion = "6.2.1"
-    postgresqlVersion = "42.7.4"
-    vertxVersion = "4.5.11"
+    postgresqlVersion = "42.7.5"
+    vertxVersion = "4.5.12"
     cache2kVersion = "2.6.1.Final"
     cache2kVersion = "2.6.1.Final"
 
 
-    applicationClass = "com.hexagonkt.BenchmarkKt"
+    applicationClass = "com.hexagontk.BenchmarkKt"
     modules = "java.naming,java.sql,java.management"
     modules = "java.naming,java.sql,java.management"
-    gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/$hexagonVersion/gradle"
+    gradleScripts = "https://raw.githubusercontent.com/hexagontk/hexagon/$hexagonVersion/gradle"
 }
 }
 
 
 subprojects {
 subprojects {
@@ -30,5 +30,5 @@ subprojects {
 }
 }
 
 
 tasks.wrapper {
 tasks.wrapper {
-    gradleVersion = "8.10.2"
+    gradleVersion = "8.12.1"
 }
 }

+ 2 - 2
frameworks/Kotlin/hexagon/config.toml

@@ -19,7 +19,7 @@ platform = "Servlet"
 webserver = "None"
 webserver = "None"
 versus = "servlet"
 versus = "servlet"
 
 
-[jettyloom]
+[jdk]
 urls.plaintext = "/plaintext"
 urls.plaintext = "/plaintext"
 urls.json = "/json"
 urls.json = "/json"
 urls.db = "/db"
 urls.db = "/db"
@@ -37,7 +37,7 @@ platform = "Servlet"
 webserver = "None"
 webserver = "None"
 versus = "servlet"
 versus = "servlet"
 
 
-[jettyloom-pgclient]
+[jdk-pgclient]
 urls.plaintext = "/plaintext"
 urls.plaintext = "/plaintext"
 urls.json = "/json"
 urls.json = "/json"
 urls.db = "/db"
 urls.db = "/db"

+ 5 - 5
frameworks/Kotlin/hexagon/core/build.gradle

@@ -1,16 +1,16 @@
 
 
 plugins {
 plugins {
-    id("gg.jte.gradle") version("3.1.4")
+    id("gg.jte.gradle") version("3.1.13")
 }
 }
 
 
 dependencies {
 dependencies {
     api(project(":model"))
     api(project(":model"))
-    api("com.hexagonkt:http_server:$hexagonVersion")
-    api("com.hexagonkt:templates_jte:$hexagonVersion")
-    api("com.hexagonkt:serialization_jackson_json:$hexagonVersion")
+    api("com.hexagontk.http:http_server:$hexagonVersion")
+    api("com.hexagontk.templates:templates_jte:$hexagonVersion")
+    api("com.hexagontk.serialization:serialization_jackson_json:$hexagonVersion")
     api("org.cache2k:cache2k-core:$cache2kVersion")
     api("org.cache2k:cache2k-core:$cache2kVersion")
 
 
-    jteGenerate("gg.jte:jte-native-resources:3.1.4")
+    jteGenerate("gg.jte:jte-native-resources:3.1.13")
 }
 }
 
 
 tasks.register("minimizeTemplate") {
 tasks.register("minimizeTemplate") {

+ 6 - 6
frameworks/Kotlin/hexagon/core/src/main/kotlin/Benchmark.kt

@@ -1,10 +1,10 @@
-package com.hexagonkt
+package com.hexagontk
 
 
-import com.hexagonkt.http.server.HttpServer
-import com.hexagonkt.http.server.HttpServerPort
-import com.hexagonkt.http.server.HttpServerSettings
-import com.hexagonkt.store.BenchmarkStore
-import com.hexagonkt.templates.TemplatePort
+import com.hexagontk.http.server.HttpServer
+import com.hexagontk.http.server.HttpServerPort
+import com.hexagontk.http.server.HttpServerSettings
+import com.hexagontk.store.BenchmarkStore
+import com.hexagontk.templates.TemplatePort
 import java.net.InetAddress
 import java.net.InetAddress
 import java.net.URL
 import java.net.URL
 
 

+ 20 - 20
frameworks/Kotlin/hexagon/core/src/main/kotlin/Controller.kt

@@ -1,21 +1,21 @@
-package com.hexagonkt
-
-import com.hexagonkt.core.fieldsMapOf
-import com.hexagonkt.core.media.APPLICATION_JSON
-import com.hexagonkt.core.media.TEXT_HTML
-import com.hexagonkt.core.media.TEXT_PLAIN
-import com.hexagonkt.http.model.ContentType
-import com.hexagonkt.http.model.Header
-import com.hexagonkt.http.model.Headers
-import com.hexagonkt.http.server.callbacks.DateCallback
-import com.hexagonkt.http.handlers.HttpContext
-import com.hexagonkt.http.handlers.PathHandler
-import com.hexagonkt.http.handlers.path
-import com.hexagonkt.model.*
-import com.hexagonkt.serialization.jackson.json.Json
-import com.hexagonkt.serialization.serialize
-import com.hexagonkt.store.BenchmarkStore
-import com.hexagonkt.templates.TemplatePort
+package com.hexagontk
+
+import com.hexagontk.core.fieldsMapOf
+import com.hexagontk.core.media.APPLICATION_JSON
+import com.hexagontk.core.media.TEXT_HTML
+import com.hexagontk.core.media.TEXT_PLAIN
+import com.hexagontk.http.model.ContentType
+import com.hexagontk.http.model.Field
+import com.hexagontk.http.model.Headers
+import com.hexagontk.http.server.callbacks.DateCallback
+import com.hexagontk.http.handlers.HttpContext
+import com.hexagontk.http.handlers.PathHandler
+import com.hexagontk.http.handlers.path
+import com.hexagontk.model.*
+import com.hexagontk.serialization.jackson.json.Json
+import com.hexagontk.serialization.serialize
+import com.hexagontk.store.BenchmarkStore
+import com.hexagontk.templates.TemplatePort
 import java.net.URL
 import java.net.URL
 import java.util.concurrent.ThreadLocalRandom
 import java.util.concurrent.ThreadLocalRandom
 import kotlin.text.Charsets.UTF_8
 import kotlin.text.Charsets.UTF_8
@@ -35,7 +35,7 @@ class Controller(
     private val json: ContentType = ContentType(APPLICATION_JSON)
     private val json: ContentType = ContentType(APPLICATION_JSON)
     private val html: ContentType = ContentType(TEXT_HTML, charset = UTF_8)
     private val html: ContentType = ContentType(TEXT_HTML, charset = UTF_8)
 
 
-    private val headers = Headers(Header("server", "Hexagon"))
+    private val headers = Headers(Field("server", "Hexagon"))
 
 
     val path: PathHandler by lazy {
     val path: PathHandler by lazy {
         path {
         path {
@@ -105,7 +105,7 @@ class Controller(
         ok(body.serialize(Json.raw), contentType = json)
         ok(body.serialize(Json.raw), contentType = json)
 
 
     private fun HttpContext.getWorldsCount(parameter: String): Int =
     private fun HttpContext.getWorldsCount(parameter: String): Int =
-        request.queryParameters[parameter]?.string()?.toIntOrNull().let {
+        request.queryParameters[parameter]?.text?.toIntOrNull().let {
             when {
             when {
                 it == null -> 1
                 it == null -> 1
                 it < 1 -> 1
                 it < 1 -> 1

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

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

+ 4 - 1
frameworks/Kotlin/hexagon/core/src/main/resources/META-INF/native-image/com.hexagonkt.benchmark/core/native-image.properties

@@ -3,4 +3,7 @@ Args= \
   --static \
   --static \
   --libc=musl \
   --libc=musl \
   --gc=G1 \
   --gc=G1 \
-  --enable-sbom
+  --enable-sbom \
+  --initialize-at-build-time=org.slf4j.LoggerFactory \
+  --initialize-at-build-time=org.slf4j.helpers.Reporter \
+  --initialize-at-build-time=org.slf4j.LoggerFactoinitialize-at-build-timery

+ 1 - 1
frameworks/Kotlin/hexagon/core/src/main/resources/fortunes.jte

@@ -1,5 +1,5 @@
 @import java.util.*
 @import java.util.*
-@import com.hexagonkt.model.Fortune
+@import com.hexagontk.model.Fortune
 
 
 @param List<Fortune> fortunes
 @param List<Fortune> fortunes
 
 

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

@@ -1,6 +1,6 @@
 distributionBase=GRADLE_USER_HOME
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
 networkTimeout=10000
 networkTimeout=10000
 validateDistributionUrl=true
 validateDistributionUrl=true
 zipStoreBase=GRADLE_USER_HOME
 zipStoreBase=GRADLE_USER_HOME

+ 1 - 2
frameworks/Kotlin/hexagon/gradlew

@@ -86,8 +86,7 @@ done
 # shellcheck disable=SC2034
 # shellcheck disable=SC2034
 APP_BASE_NAME=${0##*/}
 APP_BASE_NAME=${0##*/}
 # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
 # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
-APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
-' "$PWD" ) || exit
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
 
 
 # Use the maximum available, or set MAX_FD != -1 to use that value.
 # Use the maximum available, or set MAX_FD != -1 to use that value.
 MAX_FD=maximum
 MAX_FD=maximum

+ 4 - 4
frameworks/Kotlin/hexagon/hexagon-jettyloom-pgclient.dockerfile → frameworks/Kotlin/hexagon/hexagon-jdk-pgclient.dockerfile

@@ -1,7 +1,7 @@
 #
 #
 # BUILD
 # BUILD
 #
 #
-FROM docker.io/bellsoft/liberica-runtime-container:jdk-all-21-cds-musl AS build
+FROM docker.io/bellsoft/liberica-runtime-container:jdk-all-23-cds-musl AS build
 USER root
 USER root
 WORKDIR /hexagon
 WORKDIR /hexagon
 
 
@@ -12,8 +12,8 @@ RUN ./gradlew --quiet -x test installDist
 #
 #
 # RUNTIME
 # RUNTIME
 #
 #
-FROM docker.io/bellsoft/liberica-runtime-container:jre-21-musl
-ARG PROJECT=hexagon_jetty_pgclient
+FROM docker.io/bellsoft/liberica-runtime-container:jre-23-musl
+ARG PROJECT=hexagon_jdk_pgclient
 
 
 ENV POSTGRESQL_DB_HOST tfb-database
 ENV POSTGRESQL_DB_HOST tfb-database
 ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA -DvirtualThreads=true
 ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA -DvirtualThreads=true
@@ -21,4 +21,4 @@ ENV maximumPoolSize 300
 
 
 COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT
 COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT
 
 
-ENTRYPOINT [ "/opt/hexagon_jetty_pgclient/bin/hexagon_jetty_pgclient" ]
+ENTRYPOINT [ "/opt/hexagon_jdk_pgclient/bin/hexagon_jdk_pgclient" ]

+ 4 - 4
frameworks/Kotlin/hexagon/hexagon-jettyloom.dockerfile → frameworks/Kotlin/hexagon/hexagon-jdk.dockerfile

@@ -1,7 +1,7 @@
 #
 #
 # BUILD
 # BUILD
 #
 #
-FROM docker.io/bellsoft/liberica-runtime-container:jdk-all-21-cds-musl AS build
+FROM docker.io/bellsoft/liberica-runtime-container:jdk-all-23-cds-musl AS build
 USER root
 USER root
 WORKDIR /hexagon
 WORKDIR /hexagon
 
 
@@ -12,8 +12,8 @@ RUN ./gradlew --quiet -x test installDist
 #
 #
 # RUNTIME
 # RUNTIME
 #
 #
-FROM docker.io/bellsoft/liberica-runtime-container:jre-21-musl
-ARG PROJECT=hexagon_jetty_postgresql
+FROM docker.io/bellsoft/liberica-runtime-container:jre-23-musl
+ARG PROJECT=hexagon_jdk_postgresql
 
 
 ENV POSTGRESQL_DB_HOST tfb-database
 ENV POSTGRESQL_DB_HOST tfb-database
 ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA -DvirtualThreads=true
 ENV JDK_JAVA_OPTIONS --enable-preview -XX:+AlwaysPreTouch -XX:+UseParallelGC -XX:+UseNUMA -DvirtualThreads=true
@@ -21,4 +21,4 @@ ENV maximumPoolSize 300
 
 
 COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT
 COPY --from=build /hexagon/$PROJECT/build/install/$PROJECT /opt/$PROJECT
 
 
-ENTRYPOINT [ "/opt/hexagon_jetty_postgresql/bin/hexagon_jetty_postgresql" ]
+ENTRYPOINT [ "/opt/hexagon_jdk_postgresql/bin/hexagon_jdk_postgresql" ]

+ 1 - 1
frameworks/Kotlin/hexagon/hexagon_helidon_pgclient/build.gradle

@@ -4,5 +4,5 @@ apply(from: "$gradleScripts/native.gradle")
 
 
 dependencies {
 dependencies {
     api(project(":store_pgclient"))
     api(project(":store_pgclient"))
-    api("com.hexagonkt:http_server_helidon:$hexagonVersion")
+    api("com.hexagontk.http:http_server_helidon:$hexagonVersion")
 }
 }

+ 9 - 9
frameworks/Kotlin/hexagon/hexagon_helidon_pgclient/src/main/kotlin/Benchmark.kt

@@ -1,18 +1,18 @@
-package com.hexagonkt
+package com.hexagontk
 
 
-import com.hexagonkt.core.Jvm.systemSettingOrNull
-import com.hexagonkt.core.media.TEXT_HTML
-import com.hexagonkt.core.urlOf
-import com.hexagonkt.http.server.helidon.HelidonServerAdapter
-import com.hexagonkt.store.BenchmarkPgClientStore
-import com.hexagonkt.templates.jte.JteAdapter
+import com.hexagontk.core.Platform.systemSettingOrNull
+import com.hexagontk.core.media.TEXT_HTML
+import com.hexagontk.core.urlOf
+import com.hexagontk.http.server.helidon.HelidonHttpServer
+import com.hexagontk.store.BenchmarkPgClientStore
+import com.hexagontk.templates.jte.Jte
 import java.time.Duration
 import java.time.Duration
 
 
 fun main() {
 fun main() {
     val store = BenchmarkPgClientStore("postgresql")
     val store = BenchmarkPgClientStore("postgresql")
-    val templateEngine = JteAdapter(TEXT_HTML, precompiled = true)
+    val templateEngine = Jte(TEXT_HTML, precompiled = true)
     val templateUrl = urlOf("classpath:fortunes.jte")
     val templateUrl = urlOf("classpath:fortunes.jte")
-    val engine = HelidonServerAdapter(
+    val engine = HelidonHttpServer(
         backlog = systemSettingOrNull("backlog") ?: (8 * 1024),
         backlog = systemSettingOrNull("backlog") ?: (8 * 1024),
         writeQueueLength = systemSettingOrNull("writeQueueLength") ?: (8 * 1024),
         writeQueueLength = systemSettingOrNull("writeQueueLength") ?: (8 * 1024),
         readTimeout = Duration.parse(systemSettingOrNull("readTimeout") ?: "PT0S"),
         readTimeout = Duration.parse(systemSettingOrNull("readTimeout") ?: "PT0S"),

+ 1 - 1
frameworks/Kotlin/hexagon/hexagon_helidon_postgresql/build.gradle

@@ -3,5 +3,5 @@ apply(from: "$gradleScripts/application.gradle")
 
 
 dependencies {
 dependencies {
     api(project(":store_sql"))
     api(project(":store_sql"))
-    api("com.hexagonkt:http_server_helidon:$hexagonVersion")
+    api("com.hexagontk.http:http_server_helidon:$hexagonVersion")
 }
 }

+ 8 - 8
frameworks/Kotlin/hexagon/hexagon_helidon_postgresql/src/main/kotlin/Benchmark.kt

@@ -1,17 +1,17 @@
-package com.hexagonkt
+package com.hexagontk
 
 
-import com.hexagonkt.core.media.TEXT_HTML
-import com.hexagonkt.core.urlOf
-import com.hexagonkt.http.server.helidon.HelidonServerAdapter
-import com.hexagonkt.store.BenchmarkSqlStore
-import com.hexagonkt.templates.jte.JteAdapter
+import com.hexagontk.core.media.TEXT_HTML
+import com.hexagontk.core.urlOf
+import com.hexagontk.http.server.helidon.HelidonHttpServer
+import com.hexagontk.store.BenchmarkSqlStore
+import com.hexagontk.templates.jte.Jte
 
 
 fun main() {
 fun main() {
     val settings = Settings()
     val settings = Settings()
     val store = BenchmarkSqlStore("postgresql")
     val store = BenchmarkSqlStore("postgresql")
-    val templateEngine = JteAdapter(TEXT_HTML, precompiled = true)
+    val templateEngine = Jte(TEXT_HTML, precompiled = true)
     val templateUrl = urlOf("classpath:fortunes.jte")
     val templateUrl = urlOf("classpath:fortunes.jte")
-    val engine = HelidonServerAdapter()
+    val engine = HelidonHttpServer()
 
 
     val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings)
     val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings)
     benchmark.server.start()
     benchmark.server.start()

+ 7 - 0
frameworks/Kotlin/hexagon/hexagon_jdk_pgclient/build.gradle

@@ -0,0 +1,7 @@
+
+apply(from: "$gradleScripts/application.gradle")
+
+dependencies {
+    api(project(":store_pgclient"))
+    api("com.hexagontk.http:http_server_jdk:$hexagonVersion")
+}

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

@@ -0,0 +1,25 @@
+package com.hexagontk
+
+import com.hexagontk.core.media.TEXT_HTML
+import com.hexagontk.core.urlOf
+import com.hexagontk.http.server.jdk.JdkHttpServer
+import com.hexagontk.store.BenchmarkPgClientStore
+import com.hexagontk.templates.jte.Jte
+import java.util.concurrent.Executors.newVirtualThreadPerTaskExecutor
+
+fun main() {
+    System.setProperty("sun.net.httpserver.idleInterval", "5")
+    System.setProperty("sun.net.httpserver.maxIdleConnections", "400")
+
+    val settings = Settings()
+    val store = BenchmarkPgClientStore("postgresql")
+    val templateEngine = Jte(TEXT_HTML, precompiled = true)
+    val templateUrl = urlOf("classpath:fortunes.jte")
+    val engine = JdkHttpServer(
+        executor = newVirtualThreadPerTaskExecutor(),
+        backlog = 2_048
+    )
+
+    val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings)
+    benchmark.server.start()
+}

+ 8 - 0
frameworks/Kotlin/hexagon/hexagon_jdk_postgresql/build.gradle

@@ -0,0 +1,8 @@
+
+apply(from: "$gradleScripts/application.gradle")
+apply(from: "$gradleScripts/native.gradle")
+
+dependencies {
+    api(project(":store_sql"))
+    api("com.hexagontk.http:http_server_jdk:$hexagonVersion")
+}

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

@@ -0,0 +1,25 @@
+package com.hexagontk
+
+import com.hexagontk.core.media.TEXT_HTML
+import com.hexagontk.core.urlOf
+import com.hexagontk.http.server.jdk.JdkHttpServer
+import com.hexagontk.store.BenchmarkSqlStore
+import com.hexagontk.templates.jte.Jte
+import java.util.concurrent.Executors.newVirtualThreadPerTaskExecutor
+
+fun main() {
+    System.setProperty("sun.net.httpserver.idleInterval", "5")
+    System.setProperty("sun.net.httpserver.maxIdleConnections", "400")
+
+    val settings = Settings()
+    val store = BenchmarkSqlStore("postgresql")
+    val templateEngine = Jte(TEXT_HTML, precompiled = true)
+    val templateUrl = urlOf("classpath:fortunes.jte")
+    val engine = JdkHttpServer(
+        executor = newVirtualThreadPerTaskExecutor(),
+        backlog = 2_048
+    )
+
+    val benchmark = Benchmark(engine, store, templateEngine, templateUrl, settings)
+    benchmark.server.start()
+}

+ 1 - 1
frameworks/Kotlin/hexagon/hexagon_jetty_pgclient/build.gradle

@@ -3,5 +3,5 @@ apply(from: "$gradleScripts/application.gradle")
 
 
 dependencies {
 dependencies {
     api(project(":store_pgclient"))
     api(project(":store_pgclient"))
-    api("com.hexagonkt:http_server_jetty:$hexagonVersion")
+    api("com.hexagontk.http:http_server_jetty:$hexagonVersion")
 }
 }

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