Browse Source

Merge pull request #39 from TechEmpower/master

aa
三刀 7 months ago
parent
commit
968ea5ce31
100 changed files with 1516 additions and 466 deletions
  1. 15 0
      frameworks/C++/poco/README.md
  2. 10 1
      frameworks/C++/poco/benchmark.cpp
  3. 6 6
      frameworks/C++/poco/poco.dockerfile
  4. 1 1
      frameworks/CSharp/aspnetcore/README.md
  5. 1 0
      frameworks/CSharp/aspnetcore/benchmark_config.json
  6. 1 1
      frameworks/CSharp/aspnetcore/src/Minimal/Minimal.csproj
  7. 2 2
      frameworks/CSharp/aspnetcore/src/Mvc/Mvc.csproj
  8. 1 1
      frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.Caching.cs
  9. 7 8
      frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.Fortunes.cs
  10. 4 4
      frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.HttpConnection.cs
  11. 1 1
      frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.Json.cs
  12. 1 1
      frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.MultipleQueries.cs
  13. 1 1
      frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.Plaintext.cs
  14. 1 1
      frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.SingleQuery.cs
  15. 1 1
      frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.Updates.cs
  16. 7 12
      frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.cs
  17. 35 8
      frameworks/CSharp/aspnetcore/src/Platform/ChunkedPipeWriter.cs
  18. 2 6
      frameworks/CSharp/aspnetcore/src/Platform/Platform.csproj
  19. 12 10
      frameworks/Elixir/phoenix/config/dev.exs
  20. 4 1
      frameworks/Elixir/phoenix/config/prod.exs
  21. 0 3
      frameworks/Elixir/phoenix/lib/hello_web.ex
  22. 1 1
      frameworks/Elixir/phoenix/lib/hello_web/controllers/page_controller.ex
  23. 0 24
      frameworks/Elixir/phoenix/lib/hello_web/gettext.ex
  24. 1 3
      frameworks/Elixir/phoenix/mix.exs
  25. 11 18
      frameworks/Elixir/phoenix/mix.lock
  26. 2 0
      frameworks/Elixir/phoenix/phoenix.dockerfile
  27. 4 2
      frameworks/FSharp/oxpecker/oxpecker.dockerfile
  28. 2 2
      frameworks/FSharp/oxpecker/src/App/App.fsproj
  29. 2 2
      frameworks/FSharp/oxpecker/src/App/Common.fs
  30. 1 3
      frameworks/FSharp/oxpecker/src/App/Db.fs
  31. 4 4
      frameworks/Go/fiber/src/go.mod
  32. 8 8
      frameworks/Go/fiber/src/go.sum
  33. 4 4
      frameworks/Go/hertz/go.mod
  34. 8 8
      frameworks/Go/hertz/go.sum
  35. 1 1
      frameworks/Java/hserver-business/README.md
  36. 5 5
      frameworks/Java/hserver-business/benchmark_config.json
  37. 3 3
      frameworks/Java/hserver-business/config.toml
  38. 14 0
      frameworks/Java/hserver-business/hserver-business.dockerfile
  39. 0 13
      frameworks/Java/hserver-business/hserver.dockerfile
  40. 2 2
      frameworks/Java/hserver-business/pom.xml
  41. 4 4
      frameworks/Java/hserver/hserver.dockerfile
  42. 1 1
      frameworks/Java/hserver/pom.xml
  43. 7 0
      frameworks/Java/hserver/src/main/java/com/test/hserver/controller/TestController.java
  44. 1 1
      frameworks/Java/micronaut/buildSrc/build.gradle
  45. 1 2
      frameworks/Java/micronaut/common/build.gradle
  46. 1 1
      frameworks/Java/micronaut/gradle.properties
  47. 1 1
      frameworks/Java/micronaut/micronaut-data-jdbc-graalvm.dockerfile
  48. 1 1
      frameworks/Java/micronaut/micronaut-data-mongodb-graalvm.dockerfile
  49. 1 1
      frameworks/Java/micronaut/micronaut-data-r2dbc-graalvm.dockerfile
  50. 0 23
      frameworks/Java/solon-vertx/README.md
  51. 0 26
      frameworks/Java/solon-vertx/benchmark_config.json
  52. 0 15
      frameworks/Java/solon-vertx/config.toml
  53. 0 61
      frameworks/Java/solon-vertx/pom.xml
  54. 0 13
      frameworks/Java/solon-vertx/solon-vertx.dockerfile
  55. 0 13
      frameworks/Java/solon-vertx/src/main/java/hello/Main.java
  56. 0 23
      frameworks/Java/solon-vertx/src/main/java/hello/controller/FilterImpl.java
  57. 0 25
      frameworks/Java/solon-vertx/src/main/java/hello/controller/HelloController.java
  58. 0 21
      frameworks/Java/solon-vertx/src/main/java/hello/model/Message.java
  59. 0 1
      frameworks/Java/solon-vertx/src/main/resources/app.properties
  60. 3 3
      frameworks/Java/solon/benchmark_config.json
  61. 2 2
      frameworks/Java/solon/config.toml
  62. 1 1
      frameworks/Java/solon/pom.xml
  63. 6 11
      frameworks/Java/solon/src/main/java/hello/repository/JdbcDbRepository.java
  64. 19 0
      frameworks/Java/tio-http-server/.dockerignore
  65. 3 0
      frameworks/Java/tio-http-server/.gitignore
  66. 114 0
      frameworks/Java/tio-http-server/README.md
  67. 227 0
      frameworks/Java/tio-http-server/api/tio-server-benchmark.md
  68. 29 0
      frameworks/Java/tio-http-server/benchmark_config.json
  69. 19 0
      frameworks/Java/tio-http-server/config.toml
  70. 209 0
      frameworks/Java/tio-http-server/pom.xml
  71. 66 0
      frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/MainApp.java
  72. 12 0
      frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/config/EhCachePluginConfig.java
  73. 22 0
      frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/config/EnjoyEngineConfig.java
  74. 31 0
      frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/config/MysqlDbConfig.java
  75. 41 0
      frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/controller/CacheController.java
  76. 127 0
      frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/controller/DbController.java
  77. 40 0
      frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/controller/IndexController.java
  78. 23 0
      frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/model/Fortune.java
  79. 12 0
      frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/model/Message.java
  80. 32 0
      frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/model/World.java
  81. 50 0
      frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/services/CacheName.java
  82. 17 0
      frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/services/CacheNameService.java
  83. 31 0
      frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/utils/BeanConverterUtils.java
  84. 36 0
      frameworks/Java/tio-http-server/src/main/java/com/litongjava/tio/http/server/utils/RandomUtils.java
  85. 9 0
      frameworks/Java/tio-http-server/src/main/resources/app.properties
  86. 9 0
      frameworks/Java/tio-http-server/src/main/resources/ehcache.xml
  87. 52 0
      frameworks/Java/tio-http-server/src/main/resources/logback.xml
  88. 20 0
      frameworks/Java/tio-http-server/src/main/resources/templates/fortunes.html
  89. 15 0
      frameworks/Java/tio-http-server/src/test/java/com/litongjava/tio/http/server/MainAppTest.java
  90. 9 0
      frameworks/Java/tio-http-server/tio-server-native.dockerfile
  91. 19 0
      frameworks/Java/tio-http-server/tio-server.dockerfile
  92. 2 1
      frameworks/JavaScript/express/app.js
  93. 0 16
      frameworks/JavaScript/express/benchmark_config.json
  94. 0 11
      frameworks/JavaScript/express/config.toml
  95. 0 11
      frameworks/JavaScript/express/express-chakra.dockerfile
  96. 1 1
      frameworks/JavaScript/express/express-mongodb.dockerfile
  97. 1 1
      frameworks/JavaScript/express/express-mysql.dockerfile
  98. 1 1
      frameworks/JavaScript/express/express-postgres.dockerfile
  99. 1 1
      frameworks/JavaScript/express/express-postgresjs.dockerfile
  100. 1 1
      frameworks/JavaScript/express/express.dockerfile

+ 15 - 0
frameworks/C++/poco/README.md

@@ -0,0 +1,15 @@
+# POCO C++ Libraries Benchmarking Test
+
+- [POCO Github Repository](https://github.com/pocoproject/poco)
+- [POCO Website](https://pocoproject.org/)
+
+## Software Versions
+
+- [buildpack-deps noble](https://hub.docker.com/_/buildpack-deps)
+- [g++ 14](https://gcc.gnu.org/gcc-14/)
+- [c++17](https://en.cppreference.com/w/cpp/17)
+- [POCO 1.13.1](https://pocoproject.org/releases/poco-1.13.1/poco-1.13.1-all.zip)
+ 
+## Test URLs
+
+- `PLAINTEXT` - [http://127.0.0.1:8080/plaintext](http://127.0.0.1:8080/plaintext) 

+ 10 - 1
frameworks/C++/poco/benchmark.cpp

@@ -6,6 +6,8 @@
 #include <Poco/Net/HTTPServerRequest.h>
 #include <Poco/Net/HTTPServerResponse.h>
 #include <Poco/Util/ServerApplication.h>
+#include <Poco/Timespan.h>
+#include <Poco/Thread.h>
 
 #include <iostream>
 #include <string>
@@ -15,7 +17,9 @@
 #define PLAIN_CONTENT_TYPE   "text/plain"
 #define RES_BODY             "Hello, World!"
 #define SERVER_NAME          "poco"
+#define MAX_CONNECTIONS      16384
 
+using namespace Poco;
 using namespace Poco::Net;
 using namespace Poco::Util;
 using namespace std;
@@ -58,7 +62,12 @@ protected:
         HTTPServerParams* hsp = new HTTPServerParams;
         hsp->setMaxThreads(stoi(args[1]));
         hsp->setKeepAlive(true);
-        HTTPServer s(new MyRequestHandlerFactory, ServerSocket(stoi(args[0]), 4000), hsp);
+        hsp->setMaxKeepAliveRequests(MAX_CONNECTIONS);
+        hsp->setMaxQueued(MAX_CONNECTIONS);
+        hsp->setThreadPriority(Thread::PRIO_HIGHEST);
+        ServerSocket socket(stoi(args[0]), MAX_CONNECTIONS);
+        socket.setBlocking(false);
+        HTTPServer s(new MyRequestHandlerFactory, socket, hsp);
         s.start();
         waitForTerminationRequest();
         s.stop();

+ 6 - 6
frameworks/C++/poco/poco.dockerfile

@@ -1,11 +1,11 @@
-FROM buildpack-deps:xenial
+FROM buildpack-deps:noble
 
 RUN apt-get update -yqq && apt-get install -yqq software-properties-common unzip cmake
 
-RUN apt-get install -yqq g++-4.8 libjson0-dev
-RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 50
+RUN apt-get install -yqq g++-14
+RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-14 50
 
-ENV POCO_VERSION 1.6.1
+ENV POCO_VERSION 1.13.3
 ENV POCO_HOME /poco
 
 WORKDIR ${POCO_HOME}
@@ -20,10 +20,10 @@ ENV LD_LIBRARY_PATH ${POCO_HOME}/lib/Linux/x86_64
 
 COPY benchmark.cpp benchmark.cpp
 
-RUN g++-4.8 \
+RUN g++-14 \
     -O3 \
     -DNDEBUG \
-    -std=c++0x \
+    -std=c++17 \
     -o \
     poco \
     benchmark.cpp \

+ 1 - 1
frameworks/CSharp/aspnetcore/README.md

@@ -6,5 +6,5 @@ See [.NET Core](http://dot.net) and [ASP.NET Core](https://github.com/dotnet/asp
 
 **Language**
 
-* C# 8.0
+* C# 13.0
 

+ 1 - 0
frameworks/CSharp/aspnetcore/benchmark_config.json

@@ -30,6 +30,7 @@
         "json_url": "/json",
         "db_url": "/db",
         "query_url": "/queries/",
+        "fortune_url": "/fortunes",
         "update_url": "/updates/",
         "cached_query_url": "/cached-worlds/",
         "port": 8080,

+ 1 - 1
frameworks/CSharp/aspnetcore/src/Minimal/Minimal.csproj

@@ -9,7 +9,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Npgsql" Version="8.0.5" />
+    <PackageReference Include="Npgsql" Version="9.0.2" />
     <PackageReference Include="Dapper" Version="2.1.35" />
     <PackageReference Include="RazorSlices" Version="0.8.1" />
   </ItemGroup>

+ 2 - 2
frameworks/CSharp/aspnetcore/src/Mvc/Mvc.csproj

@@ -9,8 +9,8 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Npgsql" Version="8.0.5" />
-    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.0-rc.2" />
+    <PackageReference Include="Npgsql" Version="9.0.2" />
+    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.2" />
   </ItemGroup>
 
 </Project>

+ 1 - 1
frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.Caching.cs

@@ -6,7 +6,7 @@ using System.Threading.Tasks;
 
 namespace PlatformBenchmarks;
 
-public partial class BenchmarkApplication
+public sealed partial class BenchmarkApplication
 {
     private static async Task Caching(PipeWriter pipeWriter, int count)
     {

+ 7 - 8
frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.Fortunes.cs

@@ -1,7 +1,7 @@
 // Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
-#if !AOT
+using System;
 using System.IO.Pipelines;
 using System.Runtime.CompilerServices;
 using System.Threading.Tasks;
@@ -9,7 +9,7 @@ using RazorSlices;
 
 namespace PlatformBenchmarks;
 
-public partial class BenchmarkApplication
+public sealed partial class BenchmarkApplication
 {
     private async Task FortunesRaw(PipeWriter pipeWriter)
     {
@@ -19,7 +19,7 @@ public partial class BenchmarkApplication
             FortunesTemplateFactory);
     }
 
-    private ValueTask OutputFortunes<TModel>(PipeWriter pipeWriter, TModel model, SliceFactory<TModel> templateFactory)
+    private ValueTask OutputFortunes<TModel>(PipeWriter pipeWriter, TModel model, Func<TModel, RazorSlice<TModel>> templateFactory)
     {
         // Render headers
         var preamble = """
@@ -39,7 +39,7 @@ public partial class BenchmarkApplication
         // Kestrel PipeWriter span size is 4K, headers above already written to first span & template output is ~1350 bytes,
         // so 2K chunk size should result in only a single span and chunk being used.
         var chunkedWriter = GetChunkedWriter(pipeWriter, chunkSizeHint: 2048);
-        var renderTask = template.RenderAsync(chunkedWriter, null, HtmlEncoder);
+        var renderTask = template.RenderAsync(chunkedWriter, HtmlEncoder);
 
         if (renderTask.IsCompletedSuccessfully)
         {
@@ -51,18 +51,17 @@ public partial class BenchmarkApplication
         return AwaitTemplateRenderTask(renderTask, chunkedWriter, template);
     }
 
-    private static async ValueTask AwaitTemplateRenderTask(ValueTask renderTask, ChunkedBufferWriter<WriterAdapter> chunkedWriter, RazorSlice template)
+    private static async ValueTask AwaitTemplateRenderTask(ValueTask renderTask, ChunkedPipeWriter chunkedWriter, RazorSlice template)
     {
         await renderTask;
         EndTemplateRendering(chunkedWriter, template);
     }
 
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
-    private static void EndTemplateRendering(ChunkedBufferWriter<WriterAdapter> chunkedWriter, RazorSlice template)
+    private static void EndTemplateRendering(ChunkedPipeWriter chunkedWriter, RazorSlice template)
     {
-        chunkedWriter.End();
+        chunkedWriter.Complete();
         ReturnChunkedWriter(chunkedWriter);
         template.Dispose();
     }
 }
-#endif

+ 4 - 4
frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.HttpConnection.cs

@@ -12,7 +12,7 @@ using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
 
 namespace PlatformBenchmarks;
 
-public partial class BenchmarkApplication : IHttpConnection
+public sealed partial class BenchmarkApplication : IHttpConnection
 {
     private State _state;
 
@@ -193,15 +193,15 @@ public partial class BenchmarkApplication : IHttpConnection
         => new(new(pipeWriter), sizeHint);
 
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
-    private static ChunkedBufferWriter<WriterAdapter> GetChunkedWriter(PipeWriter pipeWriter, int chunkSizeHint)
+    private static ChunkedPipeWriter GetChunkedWriter(PipeWriter pipeWriter, int chunkSizeHint)
     {
         var writer = ChunkedWriterPool.Get();
-        writer.SetOutput(new WriterAdapter(pipeWriter), chunkSizeHint);
+        writer.SetOutput(pipeWriter, chunkSizeHint);
         return writer;
     }
 
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
-    private static void ReturnChunkedWriter(ChunkedBufferWriter<WriterAdapter> writer) => ChunkedWriterPool.Return(writer);
+    private static void ReturnChunkedWriter(ChunkedPipeWriter writer) => ChunkedWriterPool.Return(writer);
 
     private struct WriterAdapter : IBufferWriter<byte>
     {

+ 1 - 1
frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.Json.cs

@@ -9,7 +9,7 @@ using System.Threading.Tasks;
 
 namespace PlatformBenchmarks;
 
-public partial class BenchmarkApplication
+public sealed partial class BenchmarkApplication
 {
     private readonly static uint _jsonPayloadSize = (uint)JsonSerializer.SerializeToUtf8Bytes(
         new JsonMessage { message = "Hello, World!" },

+ 1 - 1
frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.MultipleQueries.cs

@@ -8,7 +8,7 @@ using System.Text.Json.Serialization.Metadata;
 
 namespace PlatformBenchmarks;
 
-public partial class BenchmarkApplication
+public sealed partial class BenchmarkApplication
 {
     private static async Task MultipleQueries(PipeWriter pipeWriter, int count)
     {

+ 1 - 1
frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.Plaintext.cs

@@ -7,7 +7,7 @@ using System.Threading.Tasks;
 
 namespace PlatformBenchmarks;
 
-public partial class BenchmarkApplication
+public sealed partial class BenchmarkApplication
 {
     private static ReadOnlySpan<byte> _plaintextPreamble =>
         "HTTP/1.1 200 OK\r\n"u8 +

+ 1 - 1
frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.SingleQuery.cs

@@ -7,7 +7,7 @@ using System.Threading.Tasks;
 
 namespace PlatformBenchmarks;
 
-public partial class BenchmarkApplication
+public sealed partial class BenchmarkApplication
 {
     private static async Task SingleQuery(PipeWriter pipeWriter)
     {

+ 1 - 1
frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.Updates.cs

@@ -7,7 +7,7 @@ using System.Threading.Tasks;
 
 namespace PlatformBenchmarks;
 
-public partial class BenchmarkApplication
+public sealed partial class BenchmarkApplication
 {
     private static async Task Updates(PipeWriter pipeWriter, int count)
     {

+ 7 - 12
frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.cs

@@ -10,9 +10,8 @@ using System.Text.Json.Serialization;
 using System.Threading.Tasks;
 using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
 using Microsoft.Extensions.ObjectPool;
-#if !AOT
+using Platform.Templates;
 using RazorSlices;
-#endif
 
 namespace PlatformBenchmarks
 {
@@ -42,26 +41,24 @@ namespace PlatformBenchmarks
 
         public static RawDb RawDb { get; set; }
 
-        private static readonly DefaultObjectPool<ChunkedBufferWriter<WriterAdapter>> ChunkedWriterPool
+        private static readonly DefaultObjectPool<ChunkedPipeWriter> ChunkedWriterPool
             = new(new ChunkedWriterObjectPolicy());
 
-        private sealed class ChunkedWriterObjectPolicy : IPooledObjectPolicy<ChunkedBufferWriter<WriterAdapter>>
+        private sealed class ChunkedWriterObjectPolicy : IPooledObjectPolicy<ChunkedPipeWriter>
         {
-            public ChunkedBufferWriter<WriterAdapter> Create() => new();
+            public ChunkedPipeWriter Create() => new();
 
-            public bool Return(ChunkedBufferWriter<WriterAdapter> writer)
+            public bool Return(ChunkedPipeWriter writer)
             {
                 writer.Reset();
                 return true;
             }
         }
 
-#if !AOT
 #if NPGSQL
-        private readonly static SliceFactory<List<FortuneUtf8>> FortunesTemplateFactory = RazorSlice.ResolveSliceFactory<List<FortuneUtf8>>("/Templates/FortunesUtf8.cshtml");
+        private readonly static Func<List<FortuneUtf8>, RazorSlice<List<FortuneUtf8>>> FortunesTemplateFactory = FortunesUtf8.Create;
 #else
-        private readonly static SliceFactory<List<FortuneUtf16>> FortunesTemplateFactory = RazorSlice.ResolveSliceFactory<List<FortuneUtf16>>("/Templates/FortunesUtf16.cshtml");
-#endif
+        private readonly static Func<List<FortuneUtf16>, RazorSlice<List<FortuneUtf16>>> FortunesTemplateFactory = FortunesUtf16.Create;
 #endif
 
         [ThreadStatic]
@@ -167,9 +164,7 @@ namespace PlatformBenchmarks
 
         private Task ProcessRequestAsync() => _requestType switch
         {
-#if !AOT
             RequestType.FortunesRaw => FortunesRaw(Writer),
-#endif
             RequestType.SingleQuery => SingleQuery(Writer),
             RequestType.Caching => Caching(Writer, _queries),
             RequestType.Updates => Updates(Writer, _queries),

+ 35 - 8
frameworks/CSharp/aspnetcore/src/Platform/ChunkedBufferWriter.cs → frameworks/CSharp/aspnetcore/src/Platform/ChunkedPipeWriter.cs

@@ -5,35 +5,40 @@ using System;
 using System.Buffers;
 using System.Buffers.Text;
 using System.Diagnostics;
+using System.IO.Pipelines;
 using System.Numerics;
 using System.Runtime.CompilerServices;
+using System.Threading;
+using System.Threading.Tasks;
 
 namespace PlatformBenchmarks;
 
-internal sealed class ChunkedBufferWriter<TWriter> : IBufferWriter<byte> where TWriter : IBufferWriter<byte>
+internal sealed class ChunkedPipeWriter : PipeWriter
 {
     private const int DefaultChunkSizeHint = 2048;
     private static readonly StandardFormat DefaultHexFormat = GetHexFormat(DefaultChunkSizeHint);
     private static ReadOnlySpan<byte> ChunkTerminator => "\r\n"u8;
 
-    private TWriter _output;
+    private PipeWriter _output;
     private int _chunkSizeHint;
     private StandardFormat _hexFormat = DefaultHexFormat;
     private Memory<byte> _currentFullChunk;
     private Memory<byte> _currentChunk;
     private int _buffered;
+    private long _unflushedBytes;
     private bool _ended = false;
 
     public Memory<byte> Memory => _currentChunk;
 
-    public TWriter Output => _output;
+    public PipeWriter Output => _output;
 
     public int Buffered => _buffered;
 
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
-    public void SetOutput(TWriter output, int chunkSizeHint = DefaultChunkSizeHint)
+    public void SetOutput(PipeWriter output, int chunkSizeHint = DefaultChunkSizeHint)
     {
         _buffered = 0;
+        _unflushedBytes = 0;
         _chunkSizeHint = chunkSizeHint;
         _output = output;
 
@@ -44,6 +49,7 @@ internal sealed class ChunkedBufferWriter<TWriter> : IBufferWriter<byte> where T
     public void Reset()
     {
         _buffered = 0;
+        _unflushedBytes = 0;
         _output = default;
         _ended = false;
         _hexFormat = DefaultHexFormat;
@@ -51,16 +57,21 @@ internal sealed class ChunkedBufferWriter<TWriter> : IBufferWriter<byte> where T
         _currentChunk = default;
     }
 
+    public override bool CanGetUnflushedBytes => true;
+
+    public override long UnflushedBytes => _unflushedBytes;
+
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
-    public void Advance(int count)
+    public override void Advance(int count)
     {
         ThrowIfEnded();
 
         _buffered += count;
+        _unflushedBytes += count;
         _currentChunk = _currentChunk[count..];
     }
 
-    public Memory<byte> GetMemory(int sizeHint = 0)
+    public override Memory<byte> GetMemory(int sizeHint = 0)
     {
         ThrowIfEnded();
 
@@ -71,9 +82,14 @@ internal sealed class ChunkedBufferWriter<TWriter> : IBufferWriter<byte> where T
         return _currentChunk;
     }
 
-    public Span<byte> GetSpan(int sizeHint = 0) => GetMemory(sizeHint).Span;
+    public override Span<byte> GetSpan(int sizeHint = 0) => GetMemory(sizeHint).Span;
+
+    public override void CancelPendingFlush()
+    {
+        _output.CancelPendingFlush();
+    }
 
-    public void End()
+    public override void Complete(Exception exception = null)
     {
         ThrowIfEnded();
 
@@ -82,6 +98,17 @@ internal sealed class ChunkedBufferWriter<TWriter> : IBufferWriter<byte> where T
         _ended = true;
     }
 
+    public override ValueTask<FlushResult> FlushAsync(CancellationToken cancellationToken = default)
+    {
+        CommitCurrentChunk(isFinal: false);
+
+        var flushTask = _output.FlushAsync(cancellationToken);
+
+        _unflushedBytes = 0;
+
+        return flushTask;
+    }
+
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
     private static StandardFormat GetHexFormat(int maxValue)
     {

+ 2 - 6
frameworks/CSharp/aspnetcore/src/Platform/Platform.csproj

@@ -6,7 +6,6 @@
     <IsTestAssetProject>true</IsTestAssetProject>
     <LangVersion>preview</LangVersion>
     <UserSecretsId>38063504-d08c-495a-89c9-daaad2f60f31</UserSecretsId>
-    <DefineConstants Condition="'$(PublishAot)' == 'true'">AOT;$(DefineConstants)</DefineConstants>
   </PropertyGroup>
 
   <PropertyGroup>
@@ -19,15 +18,12 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="Npgsql" Version="8.0.5" />
+    <PackageReference Include="Npgsql" Version="9.0.2" />
     <PackageReference Include="MySqlConnector" Version="2.3.7" />
     <PackageReference Include="Dapper" Version="2.1.35" />
-    <PackageReference Include="RazorSlices" Version="0.7.0" Condition="$(PublishAot) != 'true'" />
+    <PackageReference Include="RazorSlices" Version="0.8.1" />
   </ItemGroup>
 
-  <PropertyGroup Condition="$(PublishAot) == 'true'">
-    <DefaultItemExcludes>$(MSBuildThisFileDirectory)Templates/**;$(DefaultItemExcludes)</DefaultItemExcludes>
-  </PropertyGroup>
   <ItemGroup Condition="$(PublishAot) == 'true'">
     <RuntimeHostConfigurationOption Include="System.Threading.ThreadPool.HillClimbing.Disable" Value="true" />
   </ItemGroup>

+ 12 - 10
frameworks/Elixir/phoenix/config/dev.exs

@@ -1,13 +1,15 @@
 import Config
 
-# For development, we disable any cache and enable
-# debugging and code reloading.
-#
-# The watchers configuration can be used to run external
-# watchers to your application. For example, we use it
-# with brunch.io to recompile .js and .css sources.
 config :hello, HelloWeb.Endpoint,
-  http: [port: 8080],
+  adapter: Bandit.PhoenixAdapter,
+  http: [
+    port: 4000,
+    ip: {0, 0, 0, 0},
+    http_options: [
+      compress: false,
+      log_protocol_errors: :verbose
+    ],
+  ],
   debug_errors: true,
   code_reloader: true,
   cache_static_lookup: false
@@ -23,10 +25,10 @@ config :hello, HelloWeb.Endpoint,
   ]
 
 config :hello, Hello.Repo,
-  username: "benchmarkdbuser",
-  password: "benchmarkdbpass",
+  username: "postgres",
+  password: "postgres",
   database: "hello_world",
-  hostname: "tfb-database"
+  hostname: "localhost"
 
 # Do not include metadata nor timestamps in development logs
 config :logger, :console, format: "[$level] $message\n"

+ 4 - 1
frameworks/Elixir/phoenix/config/prod.exs

@@ -8,7 +8,10 @@ config :hello, HelloWeb.Endpoint,
     http_options: [
       compress: false,
       log_protocol_errors: false
-    ]
+    ],
+    thousand_island_options: [
+      transport_options: [ backlog: 8192 ]
+    ],
   ],
   compress: false,
   check_origin: false,

+ 0 - 3
frameworks/Elixir/phoenix/lib/hello_web.ex

@@ -29,7 +29,6 @@ defmodule HelloWeb do
         log: false
 
       import Plug.Conn
-      import HelloWeb.Gettext
 
       unquote(verified_routes())
     end
@@ -39,8 +38,6 @@ defmodule HelloWeb do
     quote do
       use Phoenix.Component
 
-      import HelloWeb.Gettext
-
       # Routes generation with the ~p sigil
       unquote(verified_routes())
     end

+ 1 - 1
frameworks/Elixir/phoenix/lib/hello_web/controllers/page_controller.ex

@@ -78,7 +78,7 @@ defmodule HelloWeb.PageController do
     json(conn, world_updates)
   end
 
-   def plaintext(conn, _params) do
+  def plaintext(conn, _params) do
     conn
     |> put_resp_header("content-type", "text/plain")
     |> send_resp(200, "Hello, World!")

+ 0 - 24
frameworks/Elixir/phoenix/lib/hello_web/gettext.ex

@@ -1,24 +0,0 @@
-defmodule HelloWeb.Gettext do
-  @moduledoc """
-  A module providing Internationalization with a gettext-based API.
-
-  By using [Gettext](https://hexdocs.pm/gettext),
-  your module gains a set of macros for translations, for example:
-
-      import HelloWeb.Gettext
-
-      # Simple translation
-      gettext("Here is the string to translate")
-
-      # Plural translation
-      ngettext("Here is the string to translate",
-               "Here are the strings to translate",
-               3)
-
-      # Domain-based translation
-      dgettext("errors", "Here is the error message to translate")
-
-  See the [Gettext Docs](https://hexdocs.pm/gettext) for detailed usage.
-  """
-  use Gettext, otp_app: :hello
-end

+ 1 - 3
frameworks/Elixir/phoenix/mix.exs

@@ -29,15 +29,13 @@ defmodule Hello.Mixfile do
   # Type `mix help deps` for examples and options
   defp deps do
     [
-      {:bandit, "1.5.7"},
-      {:gettext, "~> 0.20"},
+      {:bandit, "~> 1.6.1"},
       {:ecto_sql, "~> 3.10"},
       {:jason, "~> 1.2"},
       {:phoenix, "~> 1.7"},
       {:phoenix_live_view, "~> 0.18"},
       {:phoenix_ecto, "~> 4.4"},
       {:phoenix_html, "~> 4.1"},
-      {:plug_cowboy, "~> 2.5"},
       {:postgrex, ">= 0.0.0"},
       {:nebulex, "~> 2.6"}
     ]

+ 11 - 18
frameworks/Elixir/phoenix/mix.lock

@@ -1,32 +1,25 @@
 %{
-  "bandit": {:hex, :bandit, "1.5.7", "6856b1e1df4f2b0cb3df1377eab7891bec2da6a7fd69dc78594ad3e152363a50", [:mix], [{:hpax, "~> 1.0.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "f2dd92ae87d2cbea2fa9aa1652db157b6cba6c405cb44d4f6dd87abba41371cd"},
-  "castore": {:hex, :castore, "1.0.8", "dedcf20ea746694647f883590b82d9e96014057aff1d44d03ec90f36a5c0dc6e", [:mix], [], "hexpm", "0b2b66d2ee742cb1d9cb8c8be3b43c3a70ee8651f37b75a8b982e036752983f1"},
-  "cowboy": {:hex, :cowboy, "2.12.0", "f276d521a1ff88b2b9b4c54d0e753da6c66dd7be6c9fca3d9418b561828a3731", [:make, :rebar3], [{:cowlib, "2.13.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "8a7abe6d183372ceb21caa2709bec928ab2b72e18a3911aa1771639bef82651e"},
-  "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
-  "cowlib": {:hex, :cowlib, "2.13.0", "db8f7505d8332d98ef50a3ef34b34c1afddec7506e4ee4dd4a3a266285d282ca", [:make, :rebar3], [], "hexpm", "e1e1284dc3fc030a64b1ad0d8382ae7e99da46c3246b815318a4b848873800a4"},
+  "bandit": {:hex, :bandit, "1.6.1", "9e01b93d72ddc21d8c576a704949e86ee6cde7d11270a1d3073787876527a48f", [:mix], [{:hpax, "~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "5a904bf010ea24b67979835e0507688e31ac873d4ffc8ed0e5413e8d77455031"},
+  "castore": {:hex, :castore, "1.0.10", "43bbeeac820f16c89f79721af1b3e092399b3a1ecc8df1a472738fd853574911", [:mix], [], "hexpm", "1b0b7ea14d889d9ea21202c43a4fa015eb913021cb535e8ed91946f4b77a8848"},
   "db_connection": {:hex, :db_connection, "2.7.0", "b99faa9291bb09892c7da373bb82cba59aefa9b36300f6145c5f201c7adf48ec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dcf08f31b2701f857dfc787fbad78223d61a32204f217f15e881dd93e4bdd3ff"},
-  "decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
-  "ecto": {:hex, :ecto, "3.12.4", "267c94d9f2969e6acc4dd5e3e3af5b05cdae89a4d549925f3008b2b7eb0b93c3", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ef04e4101688a67d061e1b10d7bc1fbf00d1d13c17eef08b71d070ff9188f747"},
+  "decimal": {:hex, :decimal, "2.2.0", "df3d06bb9517e302b1bd265c1e7f16cda51547ad9d99892049340841f3e15836", [:mix], [], "hexpm", "af8daf87384b51b7e611fb1a1f2c4d4876b65ef968fa8bd3adf44cff401c7f21"},
+  "ecto": {:hex, :ecto, "3.12.5", "4a312960ce612e17337e7cefcf9be45b95a3be6b36b6f94dfb3d8c361d631866", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "6eb18e80bef8bb57e17f5a7f068a1719fbda384d40fc37acb8eb8aeca493b6ea"},
   "ecto_sql": {:hex, :ecto_sql, "3.12.1", "c0d0d60e85d9ff4631f12bafa454bc392ce8b9ec83531a412c12a0d415a3a4d0", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.12", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "aff5b958a899762c5f09028c847569f7dfb9cc9d63bdb8133bff8a5546de6bf5"},
-  "expo": {:hex, :expo, "1.0.0", "647639267e088717232f4d4451526e7a9de31a3402af7fcbda09b27e9a10395a", [:mix], [], "hexpm", "18d2093d344d97678e8a331ca0391e85d29816f9664a25653fd7e6166827827c"},
-  "gettext": {:hex, :gettext, "0.25.0", "98a95a862a94e2d55d24520dd79256a15c87ea75b49673a2e2f206e6ebc42e5d", [:mix], [{:expo, "~> 0.5.1 or ~> 1.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "38e5d754e66af37980a94fb93bb20dcde1d2361f664b0a19f01e87296634051f"},
-  "hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"},
+  "hpax": {:hex, :hpax, "1.0.1", "c857057f89e8bd71d97d9042e009df2a42705d6d690d54eca84c8b29af0787b0", [:mix], [], "hexpm", "4e2d5a4f76ae1e3048f35ae7adb1641c36265510a2d4638157fbcb53dda38445"},
   "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
   "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"},
-  "nebulex": {:hex, :nebulex, "2.6.3", "78af348ed9f8a338871b41e0b6de718c1808e627ce03fbe86598cbda2bdda2f5", [:mix], [{:decorator, "~> 1.4", [hex: :decorator, repo: "hexpm", optional: true]}, {:shards, "~> 1.1", [hex: :shards, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "09cdcbb62f8463ffcec7cae4936425ce91e25d92a6cd37e48b5dda7c851958d5"},
-  "phoenix": {:hex, :phoenix, "1.7.14", "a7d0b3f1bc95987044ddada111e77bd7f75646a08518942c72a8440278ae7825", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "c7859bc56cc5dfef19ecfc240775dae358cbaa530231118a9e014df392ace61a"},
-  "phoenix_ecto": {:hex, :phoenix_ecto, "4.6.2", "3b83b24ab5a2eb071a20372f740d7118767c272db386831b2e77638c4dcc606d", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.1", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "3f94d025f59de86be00f5f8c5dd7b5965a3298458d21ab1c328488be3b5fcd59"},
+  "nebulex": {:hex, :nebulex, "2.6.4", "4b00706e0e676474783d988962abf74614480e13c0a32645acb89bb32b660e09", [:mix], [{:decorator, "~> 1.4", [hex: :decorator, repo: "hexpm", optional: true]}, {:shards, "~> 1.1", [hex: :shards, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "25bdabf3fb86035c8151bba60bda20f80f96ae0261db7bd4090878ff63b03581"},
+  "phoenix": {:hex, :phoenix, "1.7.17", "2fcdceecc6fb90bec26fab008f96abbd0fd93bc9956ec7985e5892cf545152ca", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "50e8ad537f3f7b0efb1509b2f75b5c918f697be6a45d48e49a30d3b7c0e464c9"},
+  "phoenix_ecto": {:hex, :phoenix_ecto, "4.6.3", "f686701b0499a07f2e3b122d84d52ff8a31f5def386e03706c916f6feddf69ef", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.1", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "909502956916a657a197f94cc1206d9a65247538de8a5e186f7537c895d95764"},
   "phoenix_html": {:hex, :phoenix_html, "4.1.1", "4c064fd3873d12ebb1388425a8f2a19348cef56e7289e1998e2d2fa758aa982e", [:mix], [], "hexpm", "f2f2df5a72bc9a2f510b21497fd7d2b86d932ec0598f0210fed4114adc546c6f"},
   "phoenix_live_view": {:hex, :phoenix_live_view, "0.20.17", "f396bbdaf4ba227b82251eb75ac0afa6b3da5e509bc0d030206374237dfc9450", [:mix], [{:floki, "~> 0.36", [hex: :floki, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a61d741ffb78c85fdbca0de084da6a48f8ceb5261a79165b5a0b59e5f65ce98b"},
   "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.3", "3168d78ba41835aecad272d5e8cd51aa87a7ac9eb836eabc42f6e57538e3731d", [:mix], [], "hexpm", "bba06bc1dcfd8cb086759f0edc94a8ba2bc8896d5331a1e2c2902bf8e36ee502"},
   "phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"},
   "plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"},
-  "plug_cowboy": {:hex, :plug_cowboy, "2.7.1", "87677ffe3b765bc96a89be7960f81703223fe2e21efa42c125fcd0127dd9d6b2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "02dbd5f9ab571b864ae39418db7811618506256f6d13b4a45037e5fe78dc5de3"},
   "plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"},
-  "postgrex": {:hex, :postgrex, "0.19.0", "f7d50e50cb42e0a185f5b9a6095125a9ab7e4abccfbe2ab820ab9aa92b71dbab", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "dba2d2a0a8637defbf2307e8629cb2526388ba7348f67d04ec77a5d6a72ecfae"},
-  "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
+  "postgrex": {:hex, :postgrex, "0.19.3", "a0bda6e3bc75ec07fca5b0a89bffd242ca209a4822a9533e7d3e84ee80707e19", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "d31c28053655b78f47f948c85bb1cf86a9c1f8ead346ba1aa0d0df017fa05b61"},
   "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"},
-  "thousand_island": {:hex, :thousand_island, "1.3.5", "6022b6338f1635b3d32406ff98d68b843ba73b3aa95cfc27154223244f3a6ca5", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2be6954916fdfe4756af3239fb6b6d75d0b8063b5df03ba76fd8a4c87849e180"},
+  "thousand_island": {:hex, :thousand_island, "1.3.7", "1da7598c0f4f5f50562c097a3f8af308ded48cd35139f0e6f17d9443e4d0c9c5", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "0139335079953de41d381a6134d8b618d53d084f558c734f2662d1a72818dd12"},
   "websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},
-  "websock_adapter": {:hex, :websock_adapter, "0.5.6", "0437fe56e093fd4ac422de33bf8fc89f7bc1416a3f2d732d8b2c8fd54792fe60", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "e04378d26b0af627817ae84c92083b7e97aca3121196679b73c73b99d0d133ea"},
+  "websock_adapter": {:hex, :websock_adapter, "0.5.8", "3b97dc94e407e2d1fc666b2fb9acf6be81a1798a2602294aac000260a7c4a47d", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "315b9a1865552212b5f35140ad194e67ce31af45bcee443d4ecb96b5fd3f3782"},
 }

+ 2 - 0
frameworks/Elixir/phoenix/phoenix.dockerfile

@@ -9,6 +9,8 @@ FROM ${BUILDER_IMAGE} AS builder
 
 ARG MIX_ENV="prod"
 
+RUN apk add --no-cache git
+
 RUN mix local.hex --force && \
     mix local.rebar --force
 

+ 4 - 2
frameworks/FSharp/oxpecker/oxpecker.dockerfile

@@ -1,11 +1,13 @@
-FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
 WORKDIR /app
 COPY src/App .
 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
 ENV ASPNETCORE_hostBuilder__reloadConfigOnChange false
 
 ENV URLS http://+:8080

+ 2 - 2
frameworks/FSharp/oxpecker/src/App/App.fsproj

@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk.Web">
 
   <PropertyGroup>
-    <TargetFramework>net8.0</TargetFramework>
+    <TargetFramework>net9.0</TargetFramework>
     <EnableDefaultContentItems>false</EnableDefaultContentItems>
   </PropertyGroup>
 
@@ -14,7 +14,7 @@
 
   <ItemGroup>
     <PackageReference Update="FSharp.Core" Version="9.0.100" />
-    <PackageReference Include="Oxpecker" Version="1.0.0" />
+    <PackageReference Include="Oxpecker" Version="1.1.1" />
     <PackageReference Include="Oxpecker.ViewEngine" Version="1.0.0" />
     <PackageReference Include="Npgsql" Version="9.0.1" />
     <PackageReference Include="SpanJson" Version="4.2.1" />

+ 2 - 2
frameworks/FSharp/oxpecker/src/App/Common.fs

@@ -26,9 +26,9 @@ module Common =
     }
 
     [<Literal>]
-    let ConnectionString = "Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=1024;NoResetOnClose=true;Enlist=false"
+    let ConnectionString = "Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=1024;NoResetOnClose=true;Enlist=false;Max Auto Prepare=4"
     [<Literal>]
-    let MultiplexedConnectionString = ConnectionString + ";Max Auto Prepare=3;Multiplexing=true"
+    let MultiplexedConnectionString = ConnectionString + ";Multiplexing=true"
 
     let FortuneComparer = {
         new IComparer<Fortune> with

+ 1 - 3
frameworks/FSharp/oxpecker/src/App/Db.fs

@@ -14,7 +14,6 @@ module Db =
             use db = new NpgsqlConnection(ConnectionString)
             use cmd = db.CreateCommand(CommandText = "SELECT id, message FROM fortune")
             do! db.OpenAsync()
-            do! cmd.PrepareAsync()
             use! rdr = cmd.ExecuteReaderAsync(CommandBehavior.CloseConnection)
             while! rdr.ReadAsync() do
                 result.Add { id = rdr.GetInt32(0); message = rdr.GetString(1) }
@@ -46,7 +45,6 @@ module Db =
             let struct(cmd', _) = createReadCommand db
             use cmd = cmd'
             do! db.OpenAsync()
-            do! cmd.PrepareAsync()
             return! readSingleRow cmd
         }
 
@@ -64,7 +62,7 @@ module Db =
 
     let loadMultipleRows (count: int) =
         task {
-            use db = new NpgsqlConnection(MultiplexedConnectionString)
+            use db = new NpgsqlConnection(ConnectionString)
             do! db.OpenAsync()
             return! readMultipleRows count db
         }

+ 4 - 4
frameworks/Go/fiber/src/go.mod

@@ -23,8 +23,8 @@ require (
 	github.com/valyala/bytebufferpool v1.0.0 // indirect
 	github.com/valyala/fasthttp v1.55.0 // indirect
 	github.com/valyala/tcplisten v1.0.0 // indirect
-	golang.org/x/crypto v0.27.0 // indirect
-	golang.org/x/sync v0.8.0 // indirect
-	golang.org/x/sys v0.25.0 // indirect
-	golang.org/x/text v0.18.0 // indirect
+	golang.org/x/crypto v0.31.0 // indirect
+	golang.org/x/sync v0.10.0 // indirect
+	golang.org/x/sys v0.28.0 // indirect
+	golang.org/x/text v0.21.0 // indirect
 )

+ 8 - 8
frameworks/Go/fiber/src/go.sum

@@ -44,16 +44,16 @@ github.com/valyala/quicktemplate v1.8.0 h1:zU0tjbIqTRgKQzFY1L42zq0qR3eh4WoQQdIdq
 github.com/valyala/quicktemplate v1.8.0/go.mod h1:qIqW8/igXt8fdrUln5kOSb+KWMaJ4Y8QUsfd1k6L2jM=
 github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
 github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
-golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
-golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
-golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
-golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
+golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
+golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
+golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
-golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
-golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
+golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
+golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

+ 4 - 4
frameworks/Go/hertz/go.mod

@@ -28,9 +28,9 @@ require (
 	github.com/tidwall/pretty v1.2.0 // indirect
 	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
 	golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
-	golang.org/x/crypto v0.17.0 // indirect
-	golang.org/x/sync v0.1.0 // indirect
-	golang.org/x/sys v0.15.0 // indirect
-	golang.org/x/text v0.14.0 // indirect
+	golang.org/x/crypto v0.31.0 // indirect
+	golang.org/x/sync v0.10.0 // indirect
+	golang.org/x/sys v0.28.0 // indirect
+	golang.org/x/text v0.21.0 // indirect
 	google.golang.org/protobuf v1.33.0 // indirect
 )

+ 8 - 8
frameworks/Go/hertz/go.sum

@@ -77,20 +77,20 @@ golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff/go.mod h1:flIaEI6LNU6xOCD5P
 golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
 golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
-golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
+golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
+golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
-golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
+golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20220110181412-a018aaa089fe/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
-golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
+golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
-golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
+golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

+ 1 - 1
frameworks/Java/hserver-business/README.md

@@ -1,4 +1,4 @@
-# HServer Benchmarking Test
+# hserver-business Benchmarking Test
 This is the HServer portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
 
 ### Tests

+ 5 - 5
frameworks/Java/hserver-business/benchmark_config.json

@@ -1,6 +1,6 @@
 
 {
-  "framework": "hserver",
+  "framework": "hserver-business",
   "tests": [
     {
       "default": {
@@ -14,17 +14,17 @@
         "approach": "Realistic",
         "classification": "Fullstack",
         "database": "Postgres",
-        "framework": "hserver",
+        "framework": "hserver-business",
         "language": "Java",
         "flavor": "None",
         "orm": "Full",
-        "platform": "hserver",
-        "webserver": "hserver",
+        "platform": "hserver-business",
+        "webserver": "hserver-business",
         "os": "Linux",
         "database_os": "Linux",
         "display_name": "hserver-business",
         "notes": "",
-        "versus": "hserver"
+        "versus": "hserver-business"
       }
     }
   ]

+ 3 - 3
frameworks/Java/hserver-business/config.toml

@@ -12,6 +12,6 @@ approach = "Realistic"
 classification = "Fullstack"
 os = "Linux"
 orm = "Full"
-platform = "hserver"
-webserver = "hserver"
-versus = "hserver"
+platform = "hserver-business"
+webserver = "hserver-business"
+versus = "hserver-business"

+ 14 - 0
frameworks/Java/hserver-business/hserver-business.dockerfile

@@ -0,0 +1,14 @@
+FROM maven:3.6.1-jdk-11-slim as maven
+WORKDIR /hserver-business
+COPY pom.xml pom.xml
+COPY src src
+RUN mvn package --quiet
+
+FROM openjdk:11.0.3-jdk-slim
+WORKDIR /hserver-business
+COPY --from=maven /hserver-business/target/hserver-business-1.0.jar app.jar
+
+EXPOSE 8888
+
+CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-XX:+AggressiveOpts", "-Dio.netty.buffer.checkBounds=false", "-Dio.netty.buffer.checkAccessible=false", "-Dio.netty.iouring.iosqeAsyncThreshold=32000", "-jar", "app.jar"]
+

+ 0 - 13
frameworks/Java/hserver-business/hserver.dockerfile

@@ -1,13 +0,0 @@
-FROM maven:3.8.4-openjdk-17-slim as maven
-WORKDIR /hserver
-COPY pom.xml pom.xml
-COPY src src
-RUN mvn package
-
-FROM openjdk:17.0.2
-WORKDIR /hserver
-COPY --from=maven /hserver/target/hserver-1.0.jar app.jar
-
-EXPOSE 8888
-
-CMD ["java", "-jar", "app.jar"]

+ 2 - 2
frameworks/Java/hserver-business/pom.xml

@@ -5,13 +5,13 @@
     <modelVersion>4.0.0</modelVersion>
 
     <groupId>com.test.hserver</groupId>
-    <artifactId>hserver</artifactId>
+    <artifactId>hserver-business</artifactId>
     <version>1.0</version>
 
     <parent>
         <artifactId>hserver-parent</artifactId>
         <groupId>cn.hserver</groupId>
-        <version>3.6.0</version>
+        <version>3.6.M3</version>
     </parent>
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

+ 4 - 4
frameworks/Java/hserver/hserver.dockerfile

@@ -1,13 +1,13 @@
-FROM maven:3.8.4-openjdk-17-slim as maven
+FROM maven:3.6.1-jdk-11-slim as maven
 WORKDIR /hserver
 COPY pom.xml pom.xml
 COPY src src
-RUN mvn package
+RUN mvn package --quiet
 
-FROM openjdk:17.0.2
+FROM openjdk:11.0.3-jdk-slim
 WORKDIR /hserver
 COPY --from=maven /hserver/target/hserver-1.0.jar app.jar
 
 EXPOSE 8888
 
-CMD ["java", "-jar", "app.jar"]
+CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-XX:+AggressiveOpts", "-Dio.netty.buffer.checkBounds=false", "-Dio.netty.buffer.checkAccessible=false", "-Dio.netty.iouring.iosqeAsyncThreshold=32000", "-jar", "app.jar"]

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

@@ -11,7 +11,7 @@
     <parent>
         <artifactId>hserver-parent</artifactId>
         <groupId>cn.hserver</groupId>
-        <version>3.6.0</version>
+        <version>3.6.M3</version>
     </parent>
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

+ 7 - 0
frameworks/Java/hserver/src/main/java/com/test/hserver/controller/TestController.java

@@ -33,6 +33,13 @@ public class TestController {
     @Autowired
     private DataSource dataSource;
 
+
+    @GET("/jso2n")
+    private   Message jso2n(long ud,int a,HttpResponse response) {
+        response.setHeader("Date", DateUtil.getTime());
+        return new Message();
+    }
+
     @GET("/json")
     public Message json(HttpResponse response) {
         response.setHeader("Date", DateUtil.getTime());

+ 1 - 1
frameworks/Java/micronaut/buildSrc/build.gradle

@@ -8,6 +8,6 @@ repositories {
 }
 
 dependencies {
-    implementation "io.micronaut.gradle:micronaut-gradle-plugin:4.4.2"
+    implementation "io.micronaut.gradle:micronaut-gradle-plugin:4.4.4"
     implementation "com.github.johnrengelman.shadow:com.github.johnrengelman.shadow.gradle.plugin:8.1.1"
 }

+ 1 - 2
frameworks/Java/micronaut/common/build.gradle

@@ -34,8 +34,7 @@ dependencies {
         transitive = false
     }
 
-    // Switch to BOM version after https://github.com/micronaut-projects/micronaut-views/issues/876
-    implementation("gg.jte:jte-runtime:3.1.12")
+    implementation("io.micronaut.views:micronaut-views-jte")
 
     runtimeOnly("ch.qos.logback:logback-classic")
     runtimeOnly("org.yaml:snakeyaml")

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

@@ -1 +1 @@
-micronautVersion=4.6.1
+micronautVersion=4.7.1

+ 1 - 1
frameworks/Java/micronaut/micronaut-data-jdbc-graalvm.dockerfile

@@ -1,4 +1,4 @@
-FROM container-registry.oracle.com/graalvm/native-image:21
+FROM container-registry.oracle.com/graalvm/native-image:23
 RUN microdnf install findutils # Gradle 8.7 requires xargs
 COPY . /home/gradle/src
 WORKDIR /home/gradle/src

+ 1 - 1
frameworks/Java/micronaut/micronaut-data-mongodb-graalvm.dockerfile

@@ -1,4 +1,4 @@
-FROM container-registry.oracle.com/graalvm/native-image:21
+FROM container-registry.oracle.com/graalvm/native-image:23
 RUN microdnf install findutils # Gradle 8.7 requires xargs
 COPY . /home/gradle/src
 WORKDIR /home/gradle/src

+ 1 - 1
frameworks/Java/micronaut/micronaut-data-r2dbc-graalvm.dockerfile

@@ -1,4 +1,4 @@
-FROM container-registry.oracle.com/graalvm/native-image:21
+FROM container-registry.oracle.com/graalvm/native-image:23
 RUN microdnf install findutils # Gradle 8.7 requires xargs
 COPY . /home/gradle/src
 WORKDIR /home/gradle/src

+ 0 - 23
frameworks/Java/solon-vertx/README.md

@@ -1,23 +0,0 @@
-# solon-vertx Benchmarking Test
-
-
-This is the solon-vertx portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
-
-### JSON Encoding Test
-* [JSON test source](src/main/java/hello/Main.java)
-* [Plaintext test source](src/main/java/hello/Main.java)
-
-## Versions
-
-* [Java OpenJDK 21](http://openjdk.java.net/)
-* [solon 3.0.2](https://github.com/noear/solon)
-
-## Test URLs
-
-### JSON Encoding Test
-
-    http://localhost:8080/json
-    
-### Plaintext Encoding Test
-
-    http://localhost:8080/plaintext

+ 0 - 26
frameworks/Java/solon-vertx/benchmark_config.json

@@ -1,26 +0,0 @@
-{
-  "framework": "solon-vertx",
-  "tests": [
-    {
-      "default": {
-        "json_url": "/json",
-        "plaintext_url": "/plaintext",
-        "port": 8080,
-        "approach": "Realistic",
-        "classification": "Fullstack",
-        "database": "None",
-        "framework": "solon",
-        "language": "Java",
-        "flavor": "None",
-        "orm": "Micro",
-        "platform": "Netty",
-        "webserver": "None",
-        "os": "Linux",
-        "database_os": "Linux",
-        "display_name": "solon-vertx",
-        "notes": "",
-        "versus": "solon"
-      }
-    }
-  ]
-}

+ 0 - 15
frameworks/Java/solon-vertx/config.toml

@@ -1,15 +0,0 @@
-[framework]
-name = "solon-vertx"
-
-[main]
-urls.plaintext = "/plaintext"
-urls.json = "/json"
-approach = "Realistic"
-classification = "Platform"
-database = "None"
-database_os = "Linux"
-os = "Linux"
-orm = "Micro"
-platform = "Netty"
-webserver = "None"
-versus = "solon"

+ 0 - 61
frameworks/Java/solon-vertx/pom.xml

@@ -1,61 +0,0 @@
-<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>
-
-    <parent>
-        <groupId>org.noear</groupId>
-        <artifactId>solon-parent</artifactId>
-        <version>3.0.2</version>
-    </parent>
-
-    <groupId>hello</groupId>
-    <artifactId>hello-solon</artifactId>
-    <version>1.0</version>
-    <packaging>jar</packaging>
-
-    <properties>
-        <java.version>21</java.version>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.noear</groupId>
-            <artifactId>solon-boot-vertx</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.noear</groupId>
-            <artifactId>solon-serialization-jackson</artifactId>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <finalName>${project.artifactId}</finalName>
-
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-assembly-plugin</artifactId>
-                <configuration>
-                    <descriptorRefs>
-                        <descriptorRef>jar-with-dependencies</descriptorRef>
-                    </descriptorRefs>
-                    <archive>
-                        <manifest>
-                            <mainClass>hello.Main</mainClass>
-                        </manifest>
-                    </archive>
-                </configuration>
-                <executions>
-                    <execution>
-                        <id>make-assembly</id>
-                        <phase>package</phase>
-                        <goals>
-                            <goal>single</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
-</project>

+ 0 - 13
frameworks/Java/solon-vertx/solon-vertx.dockerfile

@@ -1,13 +0,0 @@
-FROM maven:3.9.7-amazoncorretto-21 as maven
-WORKDIR /solon
-COPY pom.xml pom.xml
-COPY src src
-RUN mvn compile assembly:single -q
-
-FROM openjdk:21-jdk-slim
-WORKDIR /solon
-COPY --from=maven /solon/target/hello-solon.jar app.jar
-
-EXPOSE 8080
-
-CMD ["java", "-server", "-cp", "app.jar", "hello.Main"]

+ 0 - 13
frameworks/Java/solon-vertx/src/main/java/hello/Main.java

@@ -1,13 +0,0 @@
-package hello;
-
-import org.noear.solon.Solon;
-
-/**
- * @author noear
- * @version V1.0
- */
-public class Main {
-	public static void main(String[] args) {
-		Solon.start(Main.class, args);
-	}
-}

+ 0 - 23
frameworks/Java/solon-vertx/src/main/java/hello/controller/FilterImpl.java

@@ -1,23 +0,0 @@
-package hello.controller;
-
-import org.noear.solon.annotation.Component;
-import org.noear.solon.core.handle.Context;
-import org.noear.solon.core.handle.Filter;
-import org.noear.solon.core.handle.FilterChain;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-@Component
-public class FilterImpl implements Filter {
-    private static DateFormat DATE_FORMAT = new SimpleDateFormat("EEE, d MMM yyyyy HH:mm:ss z");
-
-    @Override
-    public void doFilter(Context ctx, FilterChain chain) throws Throwable {
-        String dateString = DATE_FORMAT.format(new Date());
-        ctx.headerSet("Date", dateString);
-        ctx.headerSet("Server", "solon-boot-vertx");
-        chain.doFilter(ctx);
-    }
-}

+ 0 - 25
frameworks/Java/solon-vertx/src/main/java/hello/controller/HelloController.java

@@ -1,25 +0,0 @@
-package hello.controller;
-
-import org.noear.solon.annotation.Controller;
-import org.noear.solon.annotation.Get;
-import org.noear.solon.annotation.Mapping;
-import hello.model.Message;
-
-/**
- * @author noear
- * @version V1.0
- */
-@Controller
-public class HelloController {
-    @Get
-    @Mapping("plaintext")
-    public String plaintext() {
-        return "Hello, World!";
-    }
-
-    @Get
-    @Mapping("json")
-    public Message json() {
-        return new Message("Hello, World!");
-    }
-}

+ 0 - 21
frameworks/Java/solon-vertx/src/main/java/hello/model/Message.java

@@ -1,21 +0,0 @@
-package hello.model;
-
-/**
- * @author noear
- * @version V1.0
- */
-public class Message {
-    private String message;
-
-    public Message(String message) {
-        this.message = message;
-    }
-
-    public String getMessage() {
-        return message;
-    }
-
-    public void setMessage(String message) {
-        this.message = message;
-    }
-}

+ 0 - 1
frameworks/Java/solon-vertx/src/main/resources/app.properties

@@ -1 +0,0 @@
-server.http.ioBound=false

+ 3 - 3
frameworks/Java/solon/benchmark_config.json

@@ -3,16 +3,16 @@
   "tests": [
     {
       "default": {
-        "json_url": "/json",
         "plaintext_url": "/plaintext",
+        "json_url": "/json",
         "port": 8080,
         "approach": "Realistic",
         "classification": "Fullstack",
-        "database": "None",
+        "database": "Postgres",
         "framework": "solon",
         "language": "Java",
         "flavor": "None",
-        "orm": "Full",
+        "orm": "Micro",
         "platform": "solon",
         "webserver": "smarthttp",
         "os": "Linux",

+ 2 - 2
frameworks/Java/solon/config.toml

@@ -6,10 +6,10 @@ urls.plaintext = "/plaintext"
 urls.json = "/json"
 approach = "Realistic"
 classification = "Platform"
-database = "None"
+database = "Postgres"
 database_os = "Linux"
 os = "Linux"
-orm = "Raw"
+orm = "Micro"
 platform = "solon"
 webserver = "smarthttp"
 versus = "None"

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

@@ -5,7 +5,7 @@
     <parent>
         <groupId>org.noear</groupId>
         <artifactId>solon-parent</artifactId>
-        <version>3.0.3</version>
+        <version>3.0.4</version>
     </parent>
 
     <groupId>hello</groupId>

+ 6 - 11
frameworks/Java/solon/src/main/java/hello/repository/JdbcDbRepository.java

@@ -7,7 +7,6 @@ import org.noear.solon.annotation.Inject;
 import org.noear.solon.data.sql.SqlUtils;
 
 import java.sql.SQLException;
-import java.util.ArrayList;
 import java.util.List;
 
 @Component
@@ -19,8 +18,7 @@ public class JdbcDbRepository implements DbRepository {
     public World getWorld(int id) {
         try {
             return sqlUtils.sql("SELECT id, randomnumber FROM world WHERE id = ?", id)
-                    .queryRow()
-                    .toBean(World.class, (r, t) -> new World((int) r.getObject(1), (int) r.getObject(2)));
+                    .queryRow((rs) -> new World(rs.getInt(1), rs.getInt(2)));
         } catch (Exception e) {
             return null;
         }
@@ -28,19 +26,16 @@ public class JdbcDbRepository implements DbRepository {
 
     @Override
     public void updateWorlds(List<World> worlds) throws SQLException {
-        List<Object[]> values = new ArrayList<>();
-        for (World w : worlds) {
-            values.add(new Object[]{w.randomNumber, w.id});
-        }
-
         sqlUtils.sql("UPDATE world SET randomnumber = ? WHERE id = ?")
-                .updateBatch(values);
+                .updateBatch(worlds, (ps, w) -> {
+                    ps.setInt(1, w.randomNumber);
+                    ps.setInt(2, w.id);
+                });
     }
 
     @Override
     public List<Fortune> fortunes() throws SQLException {
         return sqlUtils.sql("SELECT id, message FROM fortune")
-                .queryRowList()
-                .toBeanList(Fortune.class, (r, t) -> new Fortune((int) r.getObject(1), (String) r.getObject(2)));
+                .queryRowList((r) -> new Fortune(r.getInt(1), r.getString(2)));
     }
 }

+ 19 - 0
frameworks/Java/tio-http-server/.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-http-server/.gitignore

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

+ 114 - 0
frameworks/Java/tio-http-server/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-http-server/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-http-server/benchmark_config.json

@@ -0,0 +1,29 @@
+{
+  "framework": "tio-server",
+  "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-server",
+      "language": "Java",
+      "flavor": "None",
+      "orm": "Raw",
+      "platform": "t-io",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "tio-server",
+      "notes": "tio-server",
+      "versus": "t-io"
+    }
+  }]
+}

+ 19 - 0
frameworks/Java/tio-http-server/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"

+ 209 - 0
frameworks/Java/tio-http-server/pom.xml

@@ -0,0 +1,209 @@
+<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-http-server-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>
+    <graalvm.version>23.1.1</graalvm.version>
+    <main.class>com.litongjava.tio.http.server.MainApp</main.class>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>com.litongjava</groupId>
+      <artifactId>tio-http-server</artifactId>
+      <version>3.7.3.v20240919-RELEASE</version>
+    </dependency>
+    <dependency>
+      <groupId>com.litongjava</groupId>
+      <artifactId>java-db</artifactId>
+      <version>1.2.6</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.12</version>
+      <scope>test</scope>
+    </dependency>
+
+
+    <!-- https://mvnrepository.com/artifact/com.jfinal/activerecord -->
+    <!--
+    <dependency>
+      <groupId>com.jfinal</groupId>
+      <artifactId>activerecord</artifactId>
+      <version>5.1.6</version>
+    </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>
+  <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>
+
+    <!-- 生产环境 -->
+    <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>
+</project>

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

@@ -0,0 +1,66 @@
+package com.litongjava.tio.http.server;
+
+import com.litongjava.tio.http.common.HttpConfig;
+import com.litongjava.tio.http.common.handler.ITioHttpRequestHandler;
+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.CacheController;
+import com.litongjava.tio.http.server.controller.DbController;
+import com.litongjava.tio.http.server.controller.IndexController;
+import com.litongjava.tio.http.server.handler.DefaultHttpRequestDispatcher;
+import com.litongjava.tio.http.server.router.DefaultHttpReqeustRouter;
+import com.litongjava.tio.http.server.router.HttpRequestRouter;
+import com.litongjava.tio.server.ServerTioConfig;
+import com.litongjava.tio.utils.environment.EnvUtils;
+
+public class MainApp {
+
+  public static void main(String[] args) {
+    long start = System.currentTimeMillis();
+    EnvUtils.load();
+    // add route
+    IndexController controller = new IndexController();
+
+    HttpRequestRouter simpleHttpRoutes = new DefaultHttpReqeustRouter();
+    simpleHttpRoutes.add("/", controller::index);
+    simpleHttpRoutes.add("/plaintext", controller::plaintext);
+    simpleHttpRoutes.add("/json", controller::json);
+
+    DbController dbQueryController = new DbController();
+    simpleHttpRoutes.add("/db", dbQueryController::db);
+    simpleHttpRoutes.add("/queries", dbQueryController::queries);
+    simpleHttpRoutes.add("/updates", dbQueryController::updates);
+    simpleHttpRoutes.add("/fortunes", dbQueryController::fortunes);
+
+    CacheController cacheController = new CacheController();
+    simpleHttpRoutes.add("/cachedQuery", cacheController::cachedQuery);
+
+    // config server
+    HttpConfig httpConfig = new HttpConfig(8080, null, null, null);
+    httpConfig.setUseSession(false);
+    httpConfig.setWelcomeFile(null);
+    httpConfig.setCheckHost(false);
+    httpConfig.setCompatible1_0(false);
+
+    ITioHttpRequestHandler requestHandler = new DefaultHttpRequestDispatcher(httpConfig, simpleHttpRoutes);
+    HttpServerStarter httpServerStarter = new HttpServerStarter(httpConfig, requestHandler);
+    ServerTioConfig serverTioConfig = httpServerStarter.getServerTioConfig();
+    // close Heartbeat
+    serverTioConfig.setHeartbeatTimeout(0);
+    serverTioConfig.statOn = false;
+    // start server
+    try {
+      new MysqlDbConfig().init();
+      new EnjoyEngineConfig().engine();
+      new EhCachePluginConfig().ehCachePlugin();
+      httpServerStarter.start();
+      long end = System.currentTimeMillis();
+      System.out.println((end - start) + "ms");
+    } catch (Exception e) {
+      e.printStackTrace();
+      System.exit(1);
+    }
+
+  }
+}

+ 12 - 0
frameworks/Java/tio-http-server/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-http-server/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-http-server/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-http-server/src/main/java/com/litongjava/tio/http/server/controller/CacheController.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.Record;
+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 CacheController {
+  // 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(Record::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 Record findByIdWithCache(String tableName, int id) {
+    String sql = "SELECT id, randomNumber FROM world WHERE id = ?";
+    return Db.findFirstByCache(tableName, id, sql, id);
+  }
+}

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

@@ -0,0 +1,127 @@
+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.Record;
+import com.litongjava.ehcache.EhCache;
+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.BeanConverterUtils;
+import com.litongjava.tio.http.server.utils.RandomUtils;
+
+public class DbController {
+
+  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 = ?";
+
+    Record 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(Record::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");
+
+    EhCache.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(Record::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<Record> records = Db.find("SELECT * FROM fortune"); 
+
+    List<Fortune> fortunes = new ArrayList<>(records.size());
+    for (Record record : records) {
+      fortunes.add(BeanConverterUtils.toBean(record.toMap(), 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-http-server/src/main/java/com/litongjava/tio/http/server/controller/IndexController.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 IndexController {
+  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-server");
+  }
+
+  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-http-server/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-http-server/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-http-server/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-http-server/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-http-server/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;
+  }
+
+}

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

@@ -0,0 +1,31 @@
+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;
+  }
+}

+ 36 - 0
frameworks/Java/tio-http-server/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-http-server/src/main/resources/app.properties

@@ -0,0 +1,9 @@
+http.response.header.showServer=true
+
+#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-http-server/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-http-server/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-http-server/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-http-server/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);
+  }
+
+}

+ 9 - 0
frameworks/Java/tio-http-server/tio-server-native.dockerfile

@@ -0,0 +1,9 @@
+FROM litongjava/maven:3.8.8-graalvm-jdk-21-slim
+WORKDIR /t-io
+COPY pom.xml pom.xml
+COPY src src
+RUN mvn package -Pnative -q
+
+EXPOSE 8080
+
+CMD ["/t-io/target/tio-http-server-benchmark", " --native=true"]

+ 19 - 0
frameworks/Java/tio-http-server/tio-server.dockerfile

@@ -0,0 +1,19 @@
+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-http-server-benchmark-1.0.jar /app/target/tio-http-server-benchmark-1.0.jar
+
+EXPOSE 8080
+
+CMD ["java","-jar", "/app/target/tio-http-server-benchmark-1.0.jar"]

+ 2 - 1
frameworks/JavaScript/express/app.js

@@ -41,5 +41,6 @@ if (cluster.isPrimary) {
   app.get('/plaintext', (req, res) =>
     res.header('Content-Type', 'text/plain').send('Hello, World!'));
 
-  app.listen(8080);
+  const server = app.listen(8080);
+  server.keepAliveTimeout = 0;
 }

+ 0 - 16
frameworks/JavaScript/express/benchmark_config.json

@@ -17,22 +17,6 @@
       "display_name": "express",
       "versus": "nodejs"
     },
-    "chakra": {
-      "json_url": "/json",
-      "plaintext_url": "/plaintext",
-      "port": 8080,
-      "approach": "Realistic",
-      "classification": "Micro",
-      "framework": "express",
-      "language": "JavaScript",
-      "flavor": "node-chakracore",
-      "platform": "nodejs",
-      "webserver": "None",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "express",
-      "versus": "nodejs"
-    },
     "mongodb": {
       "db_url": "/mongoose",
       "query_url": "/mongooseq?queries=",

+ 0 - 11
frameworks/JavaScript/express/config.toml

@@ -56,14 +56,3 @@ orm = "Full"
 platform = "nodejs"
 webserver = "None"
 versus = "nodejs"
-
-[chakra]
-urls.plaintext = "/plaintext"
-urls.json = "/json"
-approach = "Realistic"
-classification = "Micro"
-database_os = "Linux"
-os = "Linux"
-platform = "nodejs"
-webserver = "None"
-versus = "nodejs"

+ 0 - 11
frameworks/JavaScript/express/express-chakra.dockerfile

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

+ 1 - 1
frameworks/JavaScript/express/express-mongodb.dockerfile

@@ -1,4 +1,4 @@
-FROM node:20.12.2-slim
+FROM node:20.16-slim
 
 COPY ./ ./
 

+ 1 - 1
frameworks/JavaScript/express/express-mysql.dockerfile

@@ -1,4 +1,4 @@
-FROM node:20.12.2-slim
+FROM node:20.16-slim
 
 COPY ./ ./
 

+ 1 - 1
frameworks/JavaScript/express/express-postgres.dockerfile

@@ -1,4 +1,4 @@
-FROM node:20.12.2-slim
+FROM node:20.16-slim
 
 COPY ./ ./
 

+ 1 - 1
frameworks/JavaScript/express/express-postgresjs.dockerfile

@@ -1,4 +1,4 @@
-FROM node:21.1.0-slim
+FROM node:20.16-slim
 
 COPY ./ ./
 

+ 1 - 1
frameworks/JavaScript/express/express.dockerfile

@@ -1,4 +1,4 @@
-FROM node:20.12.2-slim
+FROM node:20.16-slim
 
 COPY ./ ./
 

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