Просмотр исходного кода

Merge pull request #22 from TechEmpower/master

aa
三刀 3 лет назад
Родитель
Сommit
3f2e680314
75 измененных файлов с 1024 добавлено и 465 удалено
  1. 37 0
      frameworks/CSharp/fastendpoints/.gitignore
  2. 14 0
      frameworks/CSharp/fastendpoints/Benchmarks/Benchmarks.csproj
  3. 25 0
      frameworks/CSharp/fastendpoints/Benchmarks/Benchmarks.sln
  4. 21 0
      frameworks/CSharp/fastendpoints/Benchmarks/Endpoints/JsonEndpoint.cs
  5. 17 0
      frameworks/CSharp/fastendpoints/Benchmarks/Endpoints/PlainTextEndpoint.cs
  6. 9 0
      frameworks/CSharp/fastendpoints/Benchmarks/Program.cs
  7. 8 0
      frameworks/CSharp/fastendpoints/Benchmarks/appsettings.Development.json
  8. 15 0
      frameworks/CSharp/fastendpoints/Benchmarks/appsettings.json
  9. 26 0
      frameworks/CSharp/fastendpoints/README.md
  10. 26 0
      frameworks/CSharp/fastendpoints/benchmark_config.json
  11. 15 0
      frameworks/CSharp/fastendpoints/config.toml
  12. 12 0
      frameworks/CSharp/fastendpoints/fastendpoints.dockerfile
  13. 4 0
      frameworks/Dart/angel3/.gitignore
  14. 1 1
      frameworks/Dart/angel3/README.md
  15. 1 1
      frameworks/Dart/angel3/angel3.dockerfile
  16. 1 0
      frameworks/Dart/angel3/orm/config/default.yaml
  17. 2 0
      frameworks/Dart/angel3/orm/config/development.yaml
  18. 5 1
      frameworks/Dart/angel3/orm/lib/src/config/config.dart
  19. 34 2
      frameworks/Dart/angel3/orm/lib/src/config/plugins/orm.dart
  20. 14 5
      frameworks/Dart/angel3/orm/lib/src/routes/controllers/controllers.dart
  21. 53 25
      frameworks/Dart/angel3/orm/pubspec.lock
  22. 11 2
      frameworks/Dart/angel3/orm/pubspec.yaml
  23. 28 0
      frameworks/Dart/angel3/orm/run/dev.dart
  24. 20 0
      frameworks/Dart/angel3/orm/templates/fortunes.mustache
  25. 43 0
      frameworks/Dart/angel3/orm/test/all_test.dart
  26. 1 1
      frameworks/Java/hserver/pom.xml
  27. 2 0
      frameworks/Java/hserver/src/main/java/com/test/hserver/StartApp.java
  28. 1 2
      frameworks/Java/hserver/src/main/java/com/test/hserver/util/DateUtil.java
  29. 1 1
      frameworks/Java/isocket-nio/pom.xml
  30. 1 1
      frameworks/Java/ninja-standalone/pom.xml
  31. 1 1
      frameworks/JavaScript/fastify/fastify-mysql.dockerfile
  32. 1 1
      frameworks/JavaScript/fastify/fastify-postgres.dockerfile
  33. 1 1
      frameworks/JavaScript/fastify/fastify.dockerfile
  34. 1 1
      frameworks/JavaScript/restify/restify.dockerfile
  35. 1 1
      frameworks/Kotlin/hexagon/README.md
  36. 2 2
      frameworks/Kotlin/hexagon/benchmark_config.json
  37. 4 6
      frameworks/Kotlin/hexagon/build.gradle
  38. 1 1
      frameworks/Kotlin/hexagon/config.toml
  39. 0 26
      frameworks/Kotlin/hexagon/hexagon-resin.dockerfile
  40. 20 0
      frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile
  41. 0 1
      frameworks/Kotlin/hexagon/hexagon.dockerfile
  42. 18 21
      frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt
  43. 76 52
      frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt
  44. 6 1
      frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt
  45. 16 10
      frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt
  46. 4 3
      frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt
  47. 2 2
      frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkStore.kt
  48. 12 26
      frameworks/Racket/racket/app.rkt
  49. 0 36
      frameworks/Racket/racket/config/nginx.conf.tpl
  50. 95 0
      frameworks/Racket/racket/main.rkt
  51. 56 0
      frameworks/Racket/racket/place-tcp-unit.rkt
  52. 8 7
      frameworks/Racket/racket/racket.dockerfile
  53. 1 34
      frameworks/Racket/racket/scripts/run
  54. 1 0
      frameworks/Ruby/rails/.ruby-version
  55. 2 2
      frameworks/Ruby/rails/Gemfile
  56. 94 82
      frameworks/Ruby/rails/Gemfile.lock
  57. 6 6
      frameworks/Ruby/rails/README.md
  58. 1 1
      frameworks/Ruby/rails/app/models/application_record.rb
  59. 1 1
      frameworks/Ruby/rails/bin/rails
  60. 1 1
      frameworks/Ruby/rails/config/application.rb
  61. 1 1
      frameworks/Ruby/rails/config/boot.rb
  62. 15 6
      frameworks/Ruby/rails/config/environments/development.rb
  63. 25 13
      frameworks/Ruby/rails/config/environments/production.rb
  64. 17 8
      frameworks/Ruby/rails/config/environments/test.rb
  65. 2 2
      frameworks/Ruby/rails/config/initializers/filter_parameter_logging.rb
  66. 2 1
      frameworks/Ruby/rails/rails-mysql.dockerfile
  67. 2 1
      frameworks/Ruby/rails/rails.dockerfile
  68. 8 4
      frameworks/Rust/ntex/Cargo.toml
  69. 18 20
      frameworks/Rust/ntex/src/db.rs
  70. 18 14
      frameworks/Rust/ntex/src/main.rs
  71. 21 20
      frameworks/Rust/ntex/src/main_db.rs
  72. 2 2
      frameworks/Rust/ntex/src/main_plt.rs
  73. 9 1
      frameworks/Rust/ntex/src/utils.rs
  74. 2 2
      frameworks/Scala/finagle/build.sbt
  75. 2 2
      frameworks/Scala/finatra/build.sbt

+ 37 - 0
frameworks/CSharp/fastendpoints/.gitignore

@@ -0,0 +1,37 @@
+[Oo]bj/
+[Bb]in/
+TestResults/
+.nuget/
+*.sln.ide/
+_ReSharper.*/
+.idea/
+packages/
+artifacts/
+PublishProfiles/
+.vs/
+*.user
+*.suo
+*.cache
+*.docstates
+_ReSharper.*
+nuget.exe
+*net45.csproj
+*net451.csproj
+*k10.csproj
+*.psess
+*.vsp
+*.pidb
+*.userprefs
+*DS_Store
+*.ncrunchsolution
+*.*sdf
+*.ipch
+*.swp
+*~
+.build/
+.testPublish/
+launchSettings.json
+BenchmarkDotNet.Artifacts/
+BDN.Generated/
+binaries/
+global.json

+ 14 - 0
frameworks/CSharp/fastendpoints/Benchmarks/Benchmarks.csproj

@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+    <PropertyGroup>
+        <TargetFramework>net6.0</TargetFramework>
+        <Nullable>enable</Nullable>
+        <ImplicitUsings>enable</ImplicitUsings>
+        <NoWarn>CA2016;IDE1006</NoWarn>
+    </PropertyGroup>
+
+    <ItemGroup>
+        <PackageReference Include="FastEndpoints" Version="2.17.0" />
+    </ItemGroup>
+
+</Project>

+ 25 - 0
frameworks/CSharp/fastendpoints/Benchmarks/Benchmarks.sln

@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.32002.185
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "Benchmarks.csproj", "{95F15ACC-FFB8-4C45-BF4E-6E2B602C1EBA}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{95F15ACC-FFB8-4C45-BF4E-6E2B602C1EBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{95F15ACC-FFB8-4C45-BF4E-6E2B602C1EBA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{95F15ACC-FFB8-4C45-BF4E-6E2B602C1EBA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{95F15ACC-FFB8-4C45-BF4E-6E2B602C1EBA}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {975848F3-00CE-49FC-A82F-86DDC0A3CC6F}
+	EndGlobalSection
+EndGlobal

+ 21 - 0
frameworks/CSharp/fastendpoints/Benchmarks/Endpoints/JsonEndpoint.cs

@@ -0,0 +1,21 @@
+namespace Benchmarks.Endpoints;
+
+public class Response
+{
+    public string message => "Hello, World!";
+}
+
+public class JsonEndpoint : Endpoint<EmptyRequest, Response>
+{
+    public override void Configure()
+    {
+        Get("/json");
+        AllowAnonymous();
+    }
+
+    public override Task HandleAsync(EmptyRequest r, CancellationToken ct)
+    {
+        HttpContext.Response.ContentLength = 27;
+        return SendAsync(Response);
+    }
+}

+ 17 - 0
frameworks/CSharp/fastendpoints/Benchmarks/Endpoints/PlainTextEndpoint.cs

@@ -0,0 +1,17 @@
+namespace Benchmarks.Endpoints;
+
+public class PlainTextEndpoint : Endpoint<EmptyRequest, object>
+{
+    private static readonly byte[] payload = System.Text.Encoding.UTF8.GetBytes("Hello, World!");
+
+    public override void Configure()
+    {
+        Get("/plaintext");
+        AllowAnonymous();
+    }
+
+    public override Task HandleAsync(EmptyRequest r, CancellationToken ct)
+    {
+        return SendBytesAsync(payload, contentType: "text/plain");
+    }
+}

+ 9 - 0
frameworks/CSharp/fastendpoints/Benchmarks/Program.cs

@@ -0,0 +1,9 @@
+global using FastEndpoints;
+
+var builder = WebApplication.CreateBuilder();
+builder.Services.AddFastEndpoints();
+
+var app = builder.Build();
+app.UseAuthorization();
+app.UseFastEndpoints();
+app.Run();

+ 8 - 0
frameworks/CSharp/fastendpoints/Benchmarks/appsettings.Development.json

@@ -0,0 +1,8 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft.AspNetCore": "Warning"
+    }
+  }
+}

+ 15 - 0
frameworks/CSharp/fastendpoints/Benchmarks/appsettings.json

@@ -0,0 +1,15 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Warning"
+    }
+  },
+  "AllowedHosts": "*",
+  "Kestrel": {
+    "Endpoints": {
+      "Http": {
+        "Url": "http://*:8080"
+      }
+    }
+  }
+}

+ 26 - 0
frameworks/CSharp/fastendpoints/README.md

@@ -0,0 +1,26 @@
+# FastEndpoints Tests on Windows and Linux
+This includes tests for plaintext and json serialization.
+
+## Infrastructure Software Versions
+
+**Language**
+
+* C# 10.0
+
+**Platforms**
+
+* .NET Core (Windows and Linux)
+
+**Web Servers**
+
+* [Kestrel](https://github.com/dotnet/aspnetcore/tree/main/src/Servers/Kestrel)
+
+**Web Stack**
+
+* [FastEndpoints](https://fast-endpoints.com/)
+* ASP.Net 6
+
+## Paths & Source for Tests
+
+* [Plaintext](Benchmarks/Endpoints/PlainTextEndpoint.cs): "http://localhost:8080/plaintext"
+* [JSON Serialization](Benchmarks/Endpoints/JsonEndpoint.cs): "http://localhost:8080/json"

+ 26 - 0
frameworks/CSharp/fastendpoints/benchmark_config.json

@@ -0,0 +1,26 @@
+{
+  "framework": "fastendpoints",
+  "tests": [
+    {
+      "default": {
+        "plaintext_url": "/plaintext",
+        "json_url": "/json",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "database": "None",
+        "framework": "FastEndpoints",
+        "language": "C#",
+        "orm": "Raw",
+        "platform": ".NET",
+        "flavor": "CoreCLR",
+        "webserver": "Kestrel",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "FastEndpoints",
+        "notes": "",
+        "versus": "aspcore"
+      }
+    }
+  ]
+}

+ 15 - 0
frameworks/CSharp/fastendpoints/config.toml

@@ -0,0 +1,15 @@
+[framework]
+name = "fastendpoints"
+
+[main]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+approach = "Realistic"
+classification = "Micro"
+database = "None"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = ".NET"
+webserver = "Kestrel"
+versus = "aspcore"

+ 12 - 0
frameworks/CSharp/fastendpoints/fastendpoints.dockerfile

@@ -0,0 +1,12 @@
+FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
+WORKDIR /app
+COPY Benchmarks .
+RUN dotnet publish -c Release -o out
+
+FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS runtime
+WORKDIR /app
+COPY --from=build /app/out ./
+
+EXPOSE 8080
+
+ENTRYPOINT ["dotnet", "Benchmarks.dll"]

+ 4 - 0
frameworks/Dart/angel3/.gitignore

@@ -0,0 +1,4 @@
+.factorypath
+.packages
+.dart_tool
+.metals

+ 1 - 1
frameworks/Dart/angel3/README.md

@@ -44,7 +44,7 @@ http://localhost:8080/query?queries=
 
 ### UPDATE
 
-http://localhost:8080/update?queries=
+http://localhost:8080/updates?queries=
 
 ### FORTUNES
 

+ 1 - 1
frameworks/Dart/angel3/angel3.dockerfile

@@ -18,4 +18,4 @@ RUN dart pub get
 # Set environment, start server
 ENV ANGEL_ENV=production
 EXPOSE 8080
-CMD dart ./run/prod.dart -p 8080 -a 0.0.0.0
+CMD dart ./run/prod.dart -p 8080 -a 0.0.0.0 -j 20

+ 1 - 0
frameworks/Dart/angel3/orm/config/default.yaml

@@ -3,6 +3,7 @@ jwt_secret: INSECURE_DEFAULT_SECRET
 host: 127.0.0.1
 port: 8080
 postgres:
+  #host: localhost
   host: tfb-database
   port: 5432
   database_name: hello_world

+ 2 - 0
frameworks/Dart/angel3/orm/config/development.yaml

@@ -0,0 +1,2 @@
+# Development-only server configuration.
+debug: true

+ 5 - 1
frameworks/Dart/angel3/orm/lib/src/config/config.dart

@@ -2,6 +2,7 @@
 import 'package:angel3_configuration/angel3_configuration.dart';
 import 'package:angel3_framework/angel3_framework.dart';
 import 'package:angel3_jael/angel3_jael.dart';
+import 'package:jael3/jael3.dart';
 import 'package:file/file.dart';
 import 'plugins/plugins.dart' as plugins;
 
@@ -16,7 +17,10 @@ AngelConfigurer configureServer(FileSystem fileSystem) {
     // Configure our application to render Jael templates from the `views/` directory.
     //
     // See: https://github.com/angel-dart/jael
-    await app.configure(jael(fileSystem.directory('views'), minified: true));
+    var viewsDirectory = fileSystem.directory('views');
+    var viewCache = <String, Document>{};
+    jaelTemplatePreload(viewsDirectory, viewCache);
+    await app.configure(jael(viewsDirectory, cache: viewCache));
 
     // Apply another plug-ins, i.e. ones that *you* have written.
     //

+ 34 - 2
frameworks/Dart/angel3/orm/lib/src/config/plugins/orm.dart

@@ -4,17 +4,21 @@ import 'package:angel3_framework/angel3_framework.dart';
 import 'package:angel3_orm/angel3_orm.dart';
 import 'package:angel3_orm_postgres/angel3_orm_postgres.dart';
 import 'package:postgres/postgres.dart';
+import 'package:postgres_pool/postgres_pool.dart';
 
 Future<void> configureServer(Angel app) async {
+  var logger = app.environment.isProduction ? null : app.logger;
+
   var connection = await connectToPostgres(app.configuration);
   await connection.open();
-
-  var logger = app.environment.isProduction ? null : app.logger;
   var executor = PostgreSqlExecutor(connection, logger: logger);
 
+  //var executor = await connectToPostgresPool(app.configuration, logger);
+
   app
     ..container!.registerSingleton<QueryExecutor>(executor)
     ..shutdownHooks.add((_) => connection.close());
+//    ..shutdownHooks.add((_) => executor.close());
 }
 
 Future<PostgreSQLConnection> connectToPostgres(Map configuration) async {
@@ -33,3 +37,31 @@ Future<PostgreSQLConnection> connectToPostgres(Map configuration) async {
       useSSL: postgresConfig['use_ssl'] as bool? ?? false);
   return connection;
 }
+
+Future<PostgreSqlPoolExecutor> connectToPostgresPool(
+    Map configuration, dynamic logger) async {
+  var postgresConfig = configuration['postgres'] as Map? ?? {};
+  var _pool = PgPool(
+    PgEndpoint(
+        host: postgresConfig['host'] as String? ?? 'localhost',
+        port: postgresConfig['port'] as int? ?? 5432,
+        database: postgresConfig['database_name'] as String? ??
+            Platform.environment['USER'] ??
+            Platform.environment['USERNAME'] ??
+            '',
+        username: postgresConfig['username'] as String?,
+        password: postgresConfig['password'] as String?),
+    settings: PgPoolSettings()
+      ..maxConnectionAge = Duration(hours: 1)
+      ..concurrency = 10,
+  );
+
+  // Run sql to create the tables in a transaction
+  //await _pool.runTx((conn) async {
+  //  for (var s in schemas) {
+  //    await conn.execute(await File('test/migrations/$s.sql').readAsString());
+  //  }
+  //});
+
+  return PostgreSqlPoolExecutor(_pool, logger: logger);
+}

+ 14 - 5
frameworks/Dart/angel3/orm/lib/src/routes/controllers/controllers.dart

@@ -2,7 +2,6 @@ import 'dart:async';
 import 'dart:math';
 import 'package:angel3_framework/angel3_framework.dart';
 import 'package:angel3_orm/angel3_orm.dart';
-import 'package:optional/optional.dart';
 import '../../models/fortune.dart';
 import '../../models/world.dart';
 
@@ -44,9 +43,7 @@ Future configureServer(Angel app) async {
   }
 
   // Return data in json
-  app.get('/json', (req, res) async {
-    res.json({'message': 'Hello, World!'});
-  });
+  app.get('/json', (req, res) => res.json({'message': 'Hello, World!'}));
 
   // Return data in plaintext
   app.get('/plaintext', (req, res) async {
@@ -56,14 +53,21 @@ Future configureServer(Angel app) async {
 
   // Add an entry and sort a list of fortune
   app.get('/fortunes', (req, res) async {
+    //var stopwatch = Stopwatch()..start();
+
     var list = await FortuneQuery().get(executor);
 
+    //print('Query Time: ${stopwatch.elapsed.inMilliseconds}ms');
+
     list.add(
         Fortune(id: 0, message: 'Additional fortune added at request time.'));
     list.sort((a, b) => a.message?.compareTo(b.message ?? '') ?? 0);
 
+    //print('Process Time: ${stopwatch.elapsed.inMilliseconds}ms');
+    //stopwatch.stop();
+
     //res.json(list);
-    await res.render('listing', {'fortunes': list});
+    res.render('listing', {'fortunes': list});
   });
 
   // Find a random World
@@ -98,6 +102,8 @@ Future configureServer(Angel app) async {
 
   // Update a list of worlds
   app.get('/updates', (req, res) async {
+    //var stopwatch = Stopwatch()..start();
+
     var params = req.queryParameters;
     var queryLimit = _parseQueryCount(params['queries'] as String?);
     var listOfIds = _generateIds(queryLimit);
@@ -115,6 +121,9 @@ Future configureServer(Angel app) async {
       result.add(updatedRec.value);
     }
 
+    //rint('Process Time: ${stopwatch.elapsed.inMilliseconds}ms');
+    //stopwatch.stop();
+
     res.json(result);
   });
 }

+ 53 - 25
frameworks/Dart/angel3/orm/pubspec.lock

@@ -7,14 +7,14 @@ packages:
       name: _fe_analyzer_shared
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "30.0.0"
+    version: "31.0.0"
   analyzer:
     dependency: transitive
     description:
       name: analyzer
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.7.0"
+    version: "2.8.0"
   angel3_auth:
     dependency: "direct main"
     description:
@@ -49,7 +49,7 @@ packages:
       name: angel3_framework
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "4.2.2"
+    version: "4.2.3"
   angel3_hot:
     dependency: "direct dev"
     description:
@@ -70,21 +70,21 @@ packages:
       name: angel3_jael
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "4.2.1"
+    version: "4.3.1"
   angel3_migration:
     dependency: "direct main"
     description:
       name: angel3_migration
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "4.0.0"
+    version: "4.0.2"
   angel3_migration_runner:
     dependency: "direct dev"
     description:
       name: angel3_migration_runner
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "4.0.0"
+    version: "4.1.0"
   angel3_mock_request:
     dependency: transitive
     description:
@@ -98,35 +98,35 @@ packages:
       name: angel3_model
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "3.1.0"
+    version: "3.1.1"
   angel3_orm:
     dependency: "direct main"
     description:
       name: angel3_orm
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "4.0.1"
+    version: "4.0.4"
   angel3_orm_generator:
     dependency: "direct dev"
     description:
       name: angel3_orm_generator
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "4.1.1"
+    version: "4.1.3"
   angel3_orm_postgres:
     dependency: "direct main"
     description:
       name: angel3_orm_postgres
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "3.1.0"
+    version: "3.2.1"
   angel3_production:
     dependency: "direct main"
     description:
       name: angel3_production
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "3.1.1"
+    version: "3.1.2"
   angel3_route:
     dependency: transitive
     description:
@@ -280,7 +280,7 @@ packages:
       name: build
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.1.1"
+    version: "2.2.1"
   build_config:
     dependency: transitive
     description:
@@ -301,21 +301,21 @@ packages:
       name: build_resolvers
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.0.5"
+    version: "2.0.6"
   build_runner:
     dependency: "direct dev"
     description:
       name: build_runner
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.1.5"
+    version: "2.1.7"
   build_runner_core:
     dependency: transitive
     description:
       name: build_runner_core
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "7.2.2"
+    version: "7.2.3"
   built_collection:
     dependency: transitive
     description:
@@ -399,7 +399,7 @@ packages:
       name: dart_style
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.2.0"
+    version: "2.2.1"
   dotenv:
     dependency: transitive
     description:
@@ -407,6 +407,13 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "3.0.0"
+  executor:
+    dependency: transitive
+    description:
+      name: executor
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.2.2"
   file:
     dependency: transitive
     description:
@@ -492,7 +499,7 @@ packages:
     source: hosted
     version: "1.0.3"
   jael3:
-    dependency: transitive
+    dependency: "direct main"
     description:
       name: jael3
       url: "https://pub.dartlang.org"
@@ -518,7 +525,7 @@ packages:
       name: json_annotation
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "4.3.0"
+    version: "4.4.0"
   json_rpc_2:
     dependency: transitive
     description:
@@ -561,6 +568,13 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.1"
+  mysql1:
+    dependency: transitive
+    description:
+      name: mysql1
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.19.2"
   node_preamble:
     dependency: transitive
     description:
@@ -588,7 +602,7 @@ packages:
       name: path
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.8.0"
+    version: "1.8.1"
   pedantic:
     dependency: transitive
     description:
@@ -609,7 +623,14 @@ packages:
       name: postgres
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.4.2"
+    version: "2.4.3"
+  postgres_pool:
+    dependency: transitive
+    description:
+      name: postgres_pool
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.1.3"
   pub_semver:
     dependency: transitive
     description:
@@ -623,7 +644,7 @@ packages:
       name: pubspec_parse
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.0"
+    version: "1.2.0"
   quiver:
     dependency: transitive
     description:
@@ -638,6 +659,13 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "4.0.0"
+  retry:
+    dependency: transitive
+    description:
+      name: retry
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.1.0"
   sasl_scram:
     dependency: transitive
     description:
@@ -686,7 +714,7 @@ packages:
       name: source_gen
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.1"
+    version: "1.2.1"
   source_map_stack_trace:
     dependency: transitive
     description:
@@ -749,21 +777,21 @@ packages:
       name: test
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.19.4"
+    version: "1.20.1"
   test_api:
     dependency: transitive
     description:
       name: test_api
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.4.8"
+    version: "0.4.9"
   test_core:
     dependency: transitive
     description:
       name: test_core
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.4.9"
+    version: "0.4.11"
   timing:
     dependency: transitive
     description:

+ 11 - 2
frameworks/Dart/angel3/orm/pubspec.yaml

@@ -16,16 +16,25 @@ dependencies:
   angel3_production: ^3.1.0
   angel3_static: ^4.1.0
   angel3_validate: ^4.0.0
+  jael3: ^4.2.0
   belatuk_pretty_logging: ^4.0.0
   optional: ^6.0.0
   logging: ^1.0.0
 dev_dependencies:
   angel3_hot: ^4.2.0
-  angel3_migration_runner: ^4.0.0
+  angel3_migration_runner: ^4.1.0
   angel3_orm_generator: ^4.1.0
   angel3_serialize_generator: ^4.2.0
   angel3_test: ^4.0.0
   build_runner: ^2.0.3
   io: ^1.0.0
   test: ^1.17.5
-  lints: ^1.0.0
+  lints: ^1.0.0
+#dependency_overrides:
+#  angel3_orm:
+#    path: ../../../../../belatuk/packages/orm/angel_orm
+#  angel3_orm_postgres:
+#    path: ../../../../../belatuk/packages/orm/angel_orm_postgres
+#  angel3_jael:
+#    path: ../../../../../belatuk/packages/jael/angel_jael
+     

+ 28 - 0
frameworks/Dart/angel3/orm/run/dev.dart

@@ -0,0 +1,28 @@
+import 'dart:io';
+import 'package:logging/logging.dart';
+import 'package:belatuk_pretty_logging/belatuk_pretty_logging.dart';
+import 'package:angel3_container/mirrors.dart';
+import 'package:angel3_framework/angel3_framework.dart';
+import 'package:angel3_hot/angel3_hot.dart';
+import 'package:benchmark_app/benchmark_app.dart';
+
+void main() async {
+  // Watch the config/ and web/ directories for changes, and hot-reload the server.
+  hierarchicalLoggingEnabled = true;
+
+  var hot = HotReloader(() async {
+    var logger = Logger.detached('Angel3')
+      ..level = Level.ALL
+      ..onRecord.listen(prettyLog);
+    var app = Angel(logger: logger, reflector: MirrorsReflector());
+    await app.configure(configureServer);
+    return app;
+  }, [
+    Directory('config'),
+    Directory('lib'),
+  ]);
+
+  var server = await hot.startServer('127.0.0.1', 8080);
+  print(
+      'Angel3 server listening at http://${server.address.address}:${server.port}');
+}

+ 20 - 0
frameworks/Dart/angel3/orm/templates/fortunes.mustache

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Fortunes</title>
+</head>
+<body>
+<table>
+  <tr>
+    <th>id</th>
+    <th>message</th>
+  </tr>
+  {{#fortunes}}
+  <tr>
+    <td>{{id}}</td>
+    <td>{{message}}</td>
+  </tr>
+  {{/fortunes}}
+</table>
+</body>
+</html>

+ 43 - 0
frameworks/Dart/angel3/orm/test/all_test.dart

@@ -0,0 +1,43 @@
+import 'package:angel3_framework/angel3_framework.dart';
+import 'package:angel3_test/angel3_test.dart';
+import 'package:test/test.dart';
+import 'package:benchmark_app/benchmark_app.dart';
+
+// Angel also includes facilities to make testing easier.
+//
+// `package:angel_test` ships a client that can test
+// both plain HTTP and WebSockets.
+//
+// Tests do not require your server to actually be mounted on a port,
+// so they will run faster than they would in other frameworks, where you
+// would have to first bind a socket, and then account for network latency.
+//
+// See the documentation here:
+// https://github.com/angel-dart/test
+//
+// If you are unfamiliar with Dart's advanced testing library, you can read up
+// here:
+// https://github.com/dart-lang/test
+
+void main() async {
+  late TestClient client;
+
+  setUp(() async {
+    var app = Angel();
+    await app.configure(configureServer);
+
+    client = await connectTo(app);
+  });
+
+  tearDown(() async {
+    await client.close();
+  });
+
+  test('index returns 200', () async {
+    // Request a resource at the given path.
+    var response = await client.get(Uri.parse('/'));
+
+    // Expect a 200 response.
+    expect(response, hasStatus(200));
+  });
+}

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

@@ -11,7 +11,7 @@
         <dependency>
             <groupId>top.hserver</groupId>
             <artifactId>HServer</artifactId>
-            <version>2.9.73</version>
+            <version>2.9.80</version>
         </dependency>
     </dependencies>
     <build>

+ 2 - 0
frameworks/Java/hserver/src/main/java/com/test/hserver/StartApp.java

@@ -2,6 +2,7 @@ package com.test.hserver;
 
 import top.hserver.HServerApplication;
 import top.hserver.core.ioc.annotation.HServerBoot;
+import top.hserver.core.server.context.ConstConfig;
 
 /**
  * @author hxm
@@ -10,6 +11,7 @@ import top.hserver.core.ioc.annotation.HServerBoot;
 public class StartApp {
 
     public static void main(String[] args) {
+        ConstConfig.workerPool=Runtime.getRuntime().availableProcessors();
         HServerApplication.run(StartApp.class, 8888, args);
     }
 }

+ 1 - 2
frameworks/Java/hserver/src/main/java/com/test/hserver/util/DateUtil.java

@@ -10,8 +10,7 @@ import java.util.Locale;
  */
 public class DateUtil {
     private static final DateTimeFormatter GMT_FMT = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
-    private static ZoneId zoneId = ZoneId.of("GMT");
-
+    private static final ZoneId zoneId = ZoneId.of("GMT");
     public static String getNow() {
         return GMT_FMT.format(LocalDateTime.now().atZone(zoneId));
     }

+ 1 - 1
frameworks/Java/isocket-nio/pom.xml

@@ -9,7 +9,7 @@
     <properties>
         <slf4j.version>1.7.7</slf4j.version>
         <log4j.version>1.2.17</log4j.version>
-        <log4j2.version>2.17.0</log4j2.version>
+        <log4j2.version>2.17.1</log4j2.version>
         <isocket.version>1.0.3-SNAPSHOT</isocket.version>
         <fastjson.version>1.2.44</fastjson.version>
     </properties>

+ 1 - 1
frameworks/Java/ninja-standalone/pom.xml

@@ -18,7 +18,7 @@
         <maven-enforcer-plugin.version>1.4.1</maven-enforcer-plugin.version>
         <maven-war-plugin.version>3.2.0</maven-war-plugin.version>
 
-        <h2.version>1.4.197</h2.version>
+        <h2.version>2.0.206</h2.version>
         <hibernate.version>5.4.2.Final</hibernate.version>
         <hibernate-validator.version>6.0.20.Final</hibernate-validator.version>
         <jaxb-api.version>2.3.0</jaxb-api.version>

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

@@ -1,4 +1,4 @@
-FROM node:16.9.1
+FROM node:16.13.2
 
 COPY ./ ./
 

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

@@ -1,4 +1,4 @@
-FROM node:16.9.1
+FROM node:16.13.2
 
 COPY ./ ./
 

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

@@ -1,4 +1,4 @@
-FROM node:16.9.1
+FROM node:16.13.2
 
 COPY ./ ./
 

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

@@ -1,4 +1,4 @@
-FROM node:16.9.1-slim
+FROM node:16.13.2-slim
 
 WORKDIR /nextjs
 ADD ./ ./

+ 1 - 1
frameworks/Kotlin/hexagon/README.md

@@ -31,7 +31,7 @@ and `${TEMPLATE_ENGINE}` with: `pebble`
 * Database updates: http://localhost:9090/${DB_ENGINE}/update
 * Database queries: http://localhost:9090/${DB_ENGINE}/query
 
-### Resin
+### Tomcat
 
 * JSON Encoding Test: http://localhost:8080/json
 * Plain Text Test: http://localhost:8080/plaintext

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

@@ -25,7 +25,7 @@
                 "notes": "http://hexagonkt.com",
                 "versus": "servlet"
             },
-            "resin": {
+            "tomcat": {
                 "json_url": "/json",
                 "db_url": "/postgresql/db",
                 "query_url": "/postgresql/query?queries=",
@@ -44,7 +44,7 @@
                 "webserver": "None",
                 "os": "Linux",
                 "database_os": "Linux",
-                "display_name": "Hexagon Resin PostgreSQL",
+                "display_name": "Hexagon Tomcat PostgreSQL",
                 "notes": "http://hexagonkt.com",
                 "versus": "servlet"
             }

+ 4 - 6
frameworks/Kotlin/hexagon/build.gradle

@@ -4,14 +4,13 @@ plugins {
 }
 
 ext {
-    gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/1.5.1/gradle"
+    gradleScripts = "https://raw.githubusercontent.com/hexagonkt/hexagon/2.0.0/gradle"
 
-    hexagonVersion = "1.5.1"
+    hexagonVersion = "2.0.0"
     hikariVersion = "5.0.0"
-    jettyVersion = "10.0.7"
+    jettyVersion = "11.0.7"
     postgresqlVersion = "42.3.1"
     cache2kVersion = "2.4.1.Final"
-    jacksonBlackbirdVersion = "2.13.0"
 }
 
 apply(from: "$gradleScripts/kotlin.gradle")
@@ -35,9 +34,8 @@ dependencies {
     implementation("com.hexagonkt:http_server_jetty:$hexagonVersion")
     implementation("com.hexagonkt:templates_pebble:$hexagonVersion")
     implementation("com.hexagonkt:logging_slf4j_jul:$hexagonVersion")
-    implementation("com.hexagonkt:serialization_json:$hexagonVersion")
+    implementation("com.hexagonkt:serialization_jackson_json:$hexagonVersion")
 
-    implementation("com.fasterxml.jackson.module:jackson-module-blackbird:$jacksonBlackbirdVersion")
     implementation("org.cache2k:cache2k-core:$cache2kVersion")
     implementation("com.zaxxer:HikariCP:$hikariVersion")
     implementation("org.postgresql:postgresql:$postgresqlVersion")

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

@@ -19,7 +19,7 @@ platform = "Servlet"
 webserver = "None"
 versus = "servlet"
 
-[resin]
+[tomcat]
 urls.plaintext = "/plaintext"
 urls.json = "/json"
 urls.db = "/postgresql/db"

+ 0 - 26
frameworks/Kotlin/hexagon/hexagon-resin.dockerfile

@@ -1,26 +0,0 @@
-#
-# BUILD
-#
-FROM gradle:7.2-jdk11 AS gradle_build
-USER root
-WORKDIR /hexagon
-
-COPY src src
-COPY build.gradle build.gradle
-RUN gradle --quiet
-
-#
-# RUNTIME
-#
-FROM adoptopenjdk:11-jre-hotspot-bionic
-ENV DBSTORE postgresql
-ENV POSTGRESQL_DB_HOST tfb-database
-ENV RESIN http://caucho.com/download/resin-4.0.65.tar.gz
-
-WORKDIR /resin
-RUN curl -sL $RESIN | tar xz --strip-components=1
-RUN rm -rf webapps/*
-COPY --from=gradle_build /hexagon/build/libs/ROOT.war webapps/ROOT.war
-COPY src/main/resources/fortunes.pebble.html fortunes.pebble.html
-EXPOSE 8080
-CMD ["java", "-jar", "lib/resin.jar", "console"]

+ 20 - 0
frameworks/Kotlin/hexagon/hexagon-tomcat.dockerfile

@@ -0,0 +1,20 @@
+#
+# BUILD
+#
+FROM gradle:7.2-jdk11 AS gradle_build
+USER root
+WORKDIR /hexagon
+
+COPY src src
+COPY build.gradle build.gradle
+RUN gradle --quiet
+
+#
+# RUNTIME
+#
+FROM tomcat:10.0.14-jre17-temurin
+ENV DBSTORE postgresql
+ENV POSTGRESQL_DB_HOST tfb-database
+
+COPY --from=gradle_build /hexagon/build/libs/ROOT.war /usr/local/tomcat/webapps/ROOT.war
+EXPOSE 8080

+ 0 - 1
frameworks/Kotlin/hexagon/hexagon.dockerfile

@@ -17,7 +17,6 @@ ENV DBSTORE postgresql
 ENV POSTGRESQL_DB_HOST tfb-database
 ENV WEBENGINE jetty
 ENV PROJECT hexagon
-ENV ENABLE_BLACKBIRD true
 
 COPY --from=gradle_build /hexagon/build/install/$PROJECT /opt/$PROJECT
 

+ 18 - 21
frameworks/Kotlin/hexagon/src/main/kotlin/Benchmark.kt

@@ -1,47 +1,44 @@
 package com.hexagonkt
 
-import com.fasterxml.jackson.module.blackbird.BlackbirdModule
-import com.hexagonkt.core.helpers.Jvm
-import com.hexagonkt.http.server.Server
-import com.hexagonkt.http.server.ServerPort
-import com.hexagonkt.http.server.ServerSettings
+import com.hexagonkt.http.server.HttpServer
+import com.hexagonkt.http.server.HttpServerPort
+import com.hexagonkt.http.server.HttpServerSettings
 import com.hexagonkt.http.server.jetty.JettyServletAdapter
-import com.hexagonkt.serialization.*
-import com.hexagonkt.serialization.json.*
 import com.hexagonkt.store.BenchmarkSqlStore
 import com.hexagonkt.store.BenchmarkStore
 import com.hexagonkt.templates.TemplatePort
 import com.hexagonkt.templates.pebble.PebbleAdapter
 import java.net.InetAddress
 
-internal val benchmarkStores: Map<String, BenchmarkStore> by lazy {
+internal val stores: Map<String, BenchmarkStore> by lazy {
     mapOf("postgresql" to BenchmarkSqlStore("postgresql"))
 }
 
-internal val benchmarkTemplateEngines: Map<String, TemplatePort> by lazy {
+internal val templateEngines: Map<String, TemplatePort> by lazy {
     mapOf("pebble" to PebbleAdapter)
 }
 
-internal val benchmarkEngines: Map<String, ServerPort> by lazy {
+private val engines: Map<String, HttpServerPort> by lazy {
     mapOf("jetty" to JettyServletAdapter())
 }
 
-internal val benchmarkServer: Server by lazy {
+private val server: HttpServer by lazy {
     val settings = Settings()
-    val engine = benchmarkEngines[settings.webEngine] ?: error("Unsupported server engine")
-    val serverSettings = ServerSettings(
+    val engine = engines[settings.webEngine] ?: error("Unsupported server engine")
+    val controller = Controller(settings, stores, templateEngines)
+    val serverSettings = HttpServerSettings(
         bindAddress = InetAddress.getByName(settings.bindAddress),
-        bindPort = settings.bindPort
+        bindPort = settings.bindPort,
+        options = mapOf(
+            "sendDateHeader" to settings.sendDateHeader,
+            "sendServerVersion" to settings.sendServerVersion,
+            "sendXPoweredBy" to settings.sendXPoweredBy,
+        ),
     )
 
-    Server(engine, Controller(settings).router, serverSettings)
+    HttpServer(engine, controller.path, serverSettings)
 }
 
 fun main() {
-    if (Jvm.systemFlag("ENABLE_BLACKBIRD"))
-        Json.mapper.registerModule(BlackbirdModule())
-    SerializationManager.mapper = JacksonMapper
-    SerializationManager.formats = linkedSetOf(Json)
-
-    benchmarkServer.start()
+    server.start()
 }

+ 76 - 52
frameworks/Kotlin/hexagon/src/main/kotlin/Controller.kt

@@ -1,78 +1,110 @@
 package com.hexagonkt
 
-import com.hexagonkt.core.helpers.require
-import com.hexagonkt.http.server.Call
-import com.hexagonkt.http.server.Router
-import com.hexagonkt.serialization.json.Json
-import com.hexagonkt.serialization.toFieldsMap
+import com.hexagonkt.core.require
+import com.hexagonkt.core.media.ApplicationMedia.JSON
+import com.hexagonkt.core.media.TextMedia.HTML
+import com.hexagonkt.core.media.TextMedia.PLAIN
+import com.hexagonkt.http.model.ContentType
+import com.hexagonkt.http.server.handlers.HttpServerContext
+import com.hexagonkt.http.server.handlers.PathHandler
+import com.hexagonkt.http.server.handlers.path
+import com.hexagonkt.serialization.jackson.json.Json
+import com.hexagonkt.serialization.serialize
 import com.hexagonkt.store.BenchmarkStore
 import com.hexagonkt.templates.TemplatePort
+
 import java.net.URL
 import java.util.concurrent.ThreadLocalRandom
 
-class Controller(private val settings: Settings) {
+import kotlin.text.Charsets.UTF_8
 
-    private val templates: Map<String, URL> = mapOf(
-        "pebble" to (urlOrNull("classpath:fortunes.pebble.html") ?: URL("file:/resin/fortunes.pebble.html"))
-    )
-
-    internal val router: Router by lazy {
-        Router {
-            before {
-                response.headers["Server"] = "Servlet/3.1"
-                response.headers["Transfer-Encoding"] = "chunked"
-            }
+class Controller(
+    settings: Settings,
+    stores: Map<String, BenchmarkStore>,
+    templateEngines: Map<String, TemplatePort>,
+) {
+    private val queriesParam: String = settings.queriesParam
+    private val cachedQueriesParam: String = settings.cachedQueriesParam
+    private val worldRows: Int = settings.worldRows
 
-            get("/plaintext") { ok(settings.textMessage, "text/plain") }
-            get("/json") { ok(Message(settings.textMessage), Json) }
+    private val plain: ContentType = ContentType(PLAIN)
+    private val json: ContentType = ContentType(JSON)
+    private val html: ContentType = ContentType(HTML, charset = UTF_8)
 
-            benchmarkStores.forEach { (storeEngine, store) ->
-                benchmarkTemplateEngines.forEach { (templateEngineId, templateEngine) ->
-                    val path = "/$storeEngine/${templateEngineId}/fortunes"
+    private val templates: Map<String, URL> = mapOf(
+        "pebble" to URL("classpath:fortunes.pebble.html")
+    )
 
-                    get(path) { listFortunes(store, templateEngineId, templateEngine) }
+    internal val path: PathHandler by lazy {
+        path {
+            get("/plaintext") { ok(settings.textMessage, contentType = plain) }
+            get("/json") { ok(Message(settings.textMessage).serialize(Json.raw), contentType = json) }
+
+            stores.forEach { (storeEngine, store) ->
+                path("/$storeEngine") {
+                    templateEngines.forEach { (templateEngineId, templateEngine) ->
+                        get("/${templateEngineId}/fortunes") { listFortunes(store, templateEngineId, templateEngine) }
+                    }
+
+                    get("/db") { dbQuery(store) }
+                    get("/query") { getWorlds(store) }
+                    get("/cached") { getCachedWorlds(store) }
+                    get("/update") { updateWorlds(store) }
                 }
-
-                get("/$storeEngine/db") { dbQuery(store) }
-                get("/$storeEngine/query") { getWorlds(store) }
-                get("/$storeEngine/cached") { getCachedWorlds(store) }
-                get("/$storeEngine/update") { updateWorlds(store) }
             }
         }
     }
 
-    private fun Call.listFortunes(store: BenchmarkStore, templateKind: String, templateAdapter: TemplatePort) {
+    private fun HttpServerContext.listFortunes(
+        store: BenchmarkStore, templateKind: String, templateAdapter: TemplatePort
+    ): HttpServerContext {
 
         val fortunes = store.findAllFortunes() + Fortune(0, "Additional fortune added at request time.")
         val sortedFortunes = fortunes.sortedBy { it.message }
         val context = mapOf("fortunes" to sortedFortunes)
+        val body = templateAdapter.render(templates.require(templateKind), context)
 
-        response.contentType = "text/html;charset=utf-8"
-        ok(templateAdapter.render(templates.require(templateKind), context))
+        return ok(body, contentType = html)
     }
 
-    private fun Call.dbQuery(store: BenchmarkStore) {
-        ok(store.findWorlds(listOf(randomWorld())).first(), Json)
+    private fun HttpServerContext.dbQuery(store: BenchmarkStore): HttpServerContext {
+        val ids = listOf(randomWorld())
+        val worlds = store.findWorlds(ids)
+        val world = worlds.first()
+
+        return sendJson(world)
     }
 
-    private fun Call.getWorlds(store: BenchmarkStore) {
-        val ids = (1..getWorldsCount(settings.queriesParam)).map { randomWorld() }
-        ok(store.findWorlds(ids), Json)
+    private fun HttpServerContext.getWorlds(store: BenchmarkStore): HttpServerContext {
+        val worldsCount = getWorldsCount(queriesParam)
+        val ids = (1..worldsCount).map { randomWorld() }
+        val worlds = store.findWorlds(ids)
+
+        return sendJson(worlds)
     }
 
-    private fun Call.getCachedWorlds(store: BenchmarkStore) {
-        val ids = (1..getWorldsCount(settings.cachedQueriesParam)).map { randomWorld() }
-        ok(store.findCachedWorlds(ids).map { it.toFieldsMap() }, Json)
+    private fun HttpServerContext.getCachedWorlds(store: BenchmarkStore): HttpServerContext {
+        val worldsCount = getWorldsCount(cachedQueriesParam)
+        val ids = (1..worldsCount).map { randomWorld() }
+        val worlds = store.findCachedWorlds(ids)
+
+        return sendJson(worlds)
     }
 
-    private fun Call.updateWorlds(store: BenchmarkStore) {
-        val worlds = (1..getWorldsCount(settings.queriesParam)).map { World(randomWorld(), randomWorld()) }
+    private fun HttpServerContext.updateWorlds(store: BenchmarkStore): HttpServerContext {
+        val worldsCount = getWorldsCount(queriesParam)
+        val worlds = (1..worldsCount).map { World(randomWorld(), randomWorld()) }
+
         store.replaceWorlds(worlds)
-        ok(worlds, Json)
+
+        return sendJson(worlds)
     }
 
-    private fun Call.getWorldsCount(parameter: String): Int =
-        queryParametersValues[parameter]?.firstOrNull()?.toIntOrNull().let {
+    private fun HttpServerContext.sendJson(body: Any): HttpServerContext =
+        ok(body.serialize(Json.raw), contentType = json)
+
+    private fun HttpServerContext.getWorldsCount(parameter: String): Int =
+        request.queryParameters[parameter]?.toIntOrNull().let {
             when {
                 it == null -> 1
                 it < 1 -> 1
@@ -82,13 +114,5 @@ class Controller(private val settings: Settings) {
         }
 
     private fun randomWorld(): Int =
-        ThreadLocalRandom.current().nextInt(settings.worldRows) + 1
-
-    private fun urlOrNull(path: String): URL? =
-        try {
-            URL(path)
-        }
-        catch (e: Exception) {
-            null
-        }
+        ThreadLocalRandom.current().nextInt(worldRows) + 1
 }

+ 6 - 1
frameworks/Kotlin/hexagon/src/main/kotlin/Settings.kt

@@ -1,6 +1,6 @@
 package com.hexagonkt
 
-import com.hexagonkt.core.helpers.Jvm.systemSetting
+import com.hexagonkt.core.Jvm.systemSetting
 
 data class Settings(
     val bindPort: Int = systemSetting("bindPort") ?: 9090,
@@ -20,6 +20,11 @@ data class Settings(
     val worldName: String = systemSetting("worldCollection") ?: "world",
     val fortuneName: String = systemSetting("fortuneCollection") ?: "fortune",
     val databaseName: String = systemSetting("database") ?: "hello_world",
+    val databaseDriver: String = systemSetting("databaseDriver") ?: "org.postgresql.Driver",
+
+    val sendDateHeader: Boolean = systemSetting("sendDateHeader") ?: true,
+    val sendServerVersion: Boolean = systemSetting("sendServerVersion") ?: true,
+    val sendXPoweredBy: Boolean = systemSetting("sendXPoweredBy") ?: false,
 
     val worldRows: Int = 10_000,
     val textMessage: String = "Hello, World!",

+ 16 - 10
frameworks/Kotlin/hexagon/src/main/kotlin/WebListenerServer.kt

@@ -1,17 +1,23 @@
 package com.hexagonkt
 
-import com.fasterxml.jackson.module.blackbird.BlackbirdModule
+import com.hexagonkt.core.multiMapOf
+import com.hexagonkt.http.server.handlers.HttpHandler
+import com.hexagonkt.http.server.handlers.OnHandler
 import com.hexagonkt.http.server.servlet.ServletServer
-import com.hexagonkt.serialization.json.JacksonMapper
-import com.hexagonkt.serialization.json.Json
-import com.hexagonkt.serialization.SerializationManager
-import javax.servlet.annotation.WebListener
+import jakarta.servlet.annotation.WebListener
 
-@WebListener class WebListenerServer(settings: Settings = Settings()) : ServletServer(Controller(settings).router) {
+@WebListener class WebListenerServer(settings: Settings = Settings()) : ServletServer(createHandlers(settings)) {
 
-    init {
-        Json.mapper.registerModule(BlackbirdModule())
-        SerializationManager.mapper = JacksonMapper
-        SerializationManager.formats = linkedSetOf(Json)
+    private companion object {
+
+        fun createHandlers(settings: Settings): List<HttpHandler> {
+            val controller = Controller(settings, stores, templateEngines)
+            val controllerPath = controller.path
+            val serverHeaderHandler = OnHandler("*") {
+                send(headers = multiMapOf("server" to "Tomcat"))
+            }
+
+            return listOf(serverHeaderHandler, controllerPath)
+        }
     }
 }

+ 4 - 3
frameworks/Kotlin/hexagon/src/main/kotlin/store/BenchmarkSqlStore.kt

@@ -4,7 +4,7 @@ import com.hexagonkt.CachedWorld
 import com.hexagonkt.Fortune
 import com.hexagonkt.Settings
 import com.hexagonkt.World
-import com.hexagonkt.core.helpers.Jvm
+import com.hexagonkt.core.Jvm
 import com.zaxxer.hikari.HikariConfig
 import com.zaxxer.hikari.HikariDataSource
 import org.cache2k.Cache
@@ -27,8 +27,9 @@ internal class BenchmarkSqlStore(engine: String, private val settings: Settings
         val config = HikariConfig().apply {
             jdbcUrl = "jdbc:postgresql://$dbHost/${settings.databaseName}"
             maximumPoolSize = Jvm.systemSetting(Int::class, "maximumPoolSize") ?: poolSize
-            username = Jvm.systemSetting("databaseUsername") ?: "benchmarkdbuser"
-            password = Jvm.systemSetting("databasePassword") ?: "benchmarkdbpass"
+            driverClassName = settings.databaseDriver
+            username = settings.databaseUsername
+            password = settings.databasePassword
         }
         HikariDataSource(config)
     }

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

@@ -7,7 +7,7 @@ import com.hexagonkt.World
 import org.cache2k.Cache
 import org.cache2k.Cache2kBuilder
 
-internal abstract class BenchmarkStore(settings: Settings) {
+abstract class BenchmarkStore(settings: Settings) {
 
     abstract fun findAllFortunes(): List<Fortune>
     abstract fun findWorlds(ids: List<Int>): List<World>
@@ -30,4 +30,4 @@ internal abstract class BenchmarkStore(settings: Settings) {
     fun findCachedWorlds(ids: List<Int>): List<CachedWorld> {
         return ids.mapNotNull { worldsCache.get(it) }
     }
-}
+}

+ 12 - 26
frameworks/Racket/racket/app.rkt

@@ -2,17 +2,22 @@
 
 (require db
          json
+         racket/async-channel
          racket/fasl
          racket/port
          racket/serialize
-         racket/unix-socket-tcp-unit
          redis
          threading
          web-server/dispatch
          web-server/http
          web-server/http/response
+         web-server/safety-limits
+         web-server/web-server
          xml)
 
+(provide
+ start)
+
 ;; db ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (define *db*
@@ -97,8 +102,8 @@
     (query-exec *db* update-one-world (world-id r) (world-n r))))
 
 (define (world->hash r)
-  (hash 'id (world-id r)
-        'randomNumber (world-n r)))
+  (hasheq 'id (world-id r)
+          'randomNumber (world-n r)))
 
 
 ;; fortune ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -208,19 +213,7 @@
       (response/json
        (map world->hash worlds)))]))
 
-(module+ main
-  (require racket/async-channel
-           racket/cmdline
-           racket/format
-           web-server/http/response
-           web-server/safety-limits
-           web-server/web-server)
-
-  (define port
-    (command-line
-     #:args (port)
-     (string->number port)))
-
+(define (start host port tcp@)
   (define (app c req)
     (output-response c (dispatch req)))
 
@@ -228,9 +221,9 @@
   (define stop
     (serve
      #:dispatch app
-     #:listen-ip "127.0.0.1"
+     #:listen-ip host
      #:port port
-     #:tcp@ (make-unix-socket-tcp@ (format "~a.sock" port))
+     #:tcp@ tcp@
      #:confirmation-channel ch
      #:safety-limits (make-safety-limits
                       #:max-waiting 4096
@@ -242,11 +235,4 @@
   (when (exn:fail? ready-or-exn)
     (raise ready-or-exn))
 
-  (call-with-output-file (build-path (~a port ".ready"))
-    (lambda (out)
-      (displayln "ready" out)))
-
-  (with-handlers ([exn:break?
-                   (lambda (_e)
-                     (stop))])
-    (sync/enable-break never-evt)))
+  stop)

+ 0 - 36
frameworks/Racket/racket/config/nginx.conf.tpl

@@ -1,36 +0,0 @@
-daemon off;
-worker_processes $NGINX_WORKER_PROCESES;
-worker_cpu_affinity auto;
-timer_resolution 1s;
-error_log stderr error;
-
-events {
-  multi_accept on;
-  worker_connections 65535;
-}
-
-http {
-  access_log    off;
-  server_tokens off;
-  msie_padding  off;
-
-  sendfile    on;
-  tcp_nopush  on;
-  tcp_nodelay on;
-
-  keepalive_timeout  65;
-  keepalive_disable  none;
-  keepalive_requests 1000000;
-
-  include /racket/config/upstream.conf;
-
-  server {
-    listen 8080 default_server reuseport deferred backlog=65535 fastopen=4096;
-
-    location / {
-      proxy_pass            http://app;
-      proxy_http_version    1.1;
-      proxy_set_header      Connection "";
-    }
-  }
-}

+ 95 - 0
frameworks/Racket/racket/main.rkt

@@ -0,0 +1,95 @@
+#lang racket/base
+
+(require racket/cmdline
+         racket/match
+         racket/place
+         racket/tcp
+         (prefix-in app: "app.rkt")
+         "place-tcp-unit.rkt")
+
+(define (start-place)
+  (place ch
+    (define accept-ch (make-channel))
+    (define tcp (make-place-tcp@ accept-ch))
+    (define stop #f)
+
+    (let loop ([pid #f])
+      (match (sync ch)
+        [`(stop)
+         (stop)
+         (eprintf "place ~a stopped~n" pid)]
+        [`(init ,pid ,host ,port)
+         (set! stop (app:start host port tcp))
+         (eprintf "place ~a ready~n" pid)
+         (loop pid)]
+        [`(accept ,in ,out)
+         (channel-put accept-ch (list in out))
+         (loop pid)]))))
+
+(module+ main
+  (define-values (host port parallelism)
+    (let ([host "127.0.0.1"]
+          [port 8000]
+          [parallelism (processor-count)])
+      (command-line
+       #:once-each
+       [("--host" "-H") HOST "the host to listen on" (set! host HOST)]
+       [("--port" "-p") PORT "the port to bind to"
+                        (define port-num (string->number PORT))
+                        (unless (and port-num (>= port-num 0) (< port-num 65536))
+                          (eprintf "error: PORT must be a number between 0 and 65535, inclusive~n")
+                          (exit 1))
+                        (set! port port-num)]
+       [("--parallelism" "-P") PARALLELISM "the number of parallel places to run"
+                               (define n-places (string->number PARALLELISM))
+                               (unless (and n-places (positive? n-places))
+                                 (eprintf "error: PARALLELISM must be a positive number~n")
+                                 (exit 1))
+                               (set! parallelism n-places)]
+       #:args []
+       (values host port parallelism))))
+
+  (define places
+    (for/list ([pid (in-range parallelism)])
+      (define p (start-place))
+      (begin0 p
+        (place-channel-put p `(init ,pid ,host ,port)))))
+  (define (stop-places)
+    (for ([ch (in-list places)])
+      (place-channel-put ch `(stop)))
+    (for-each place-wait places))
+  (define place-fail-evt
+    (apply choice-evt (map place-dead-evt places)))
+
+  (define backlog
+    (* parallelism 4 1024))
+  (define listener
+    (tcp-listen port backlog #t host))
+  (define stop-ch (make-channel))
+  (define listener-thd
+    (thread
+     (lambda ()
+       (define places* (list->vector places))
+       (define num-places (vector-length places*))
+       (let loop ([idx 0])
+         (sync
+          (handle-evt
+           listener
+           (lambda (_)
+             (define-values (in out)
+               (tcp-accept listener))
+             (place-channel-put (vector-ref places* idx) `(accept ,in, out))
+             (loop (modulo (add1 idx) num-places))))
+          (handle-evt
+           (choice-evt stop-ch place-fail-evt)
+           (lambda (_)
+             (stop-places)
+             (tcp-close listener))))))))
+  (define (stop)
+    (channel-put stop-ch #t)
+    (thread-wait listener-thd))
+
+  (with-handlers ([exn:break?
+                   (lambda (_e)
+                     (stop))])
+    (sync/enable-break never-evt listener-thd)))

+ 56 - 0
frameworks/Racket/racket/place-tcp-unit.rkt

@@ -0,0 +1,56 @@
+#lang racket/base
+
+(require net/tcp-sig
+         (prefix-in tcp: racket/tcp)
+         racket/unit)
+
+(provide
+ make-place-tcp@)
+
+(struct place-tcp-listener ())
+
+(define (make-place-tcp@ accept-ch)
+  (unit
+    (import)
+    (export tcp^)
+
+    (define (tcp-abandon-port p)
+      (tcp:tcp-abandon-port p))
+
+    (define (tcp-accept _l)
+      (apply values (channel-get accept-ch)))
+
+    (define (tcp-accept/enable-break _l)
+      (apply values (sync/enable-break accept-ch)))
+
+    (define (tcp-accept-ready? _l)
+      (error 'tcp-accept-ready? "not supported"))
+
+    (define (tcp-addresses _p [port-numbers? #f])
+      (if port-numbers?
+          (values "127.0.0.1" 1 "127.0.0.1" 0)
+          (values "127.0.0.1" "127.0.0.1")))
+
+    (define (tcp-close _l)
+      (void))
+
+    (define (tcp-connect _hostname
+                         _port-no
+                         [_local-hostname #f]
+                         [_local-port-no #f])
+      (error 'tcp-connect "not supported"))
+
+    (define (tcp-connect/enable-break _hostname
+                                      _port-no
+                                      [_local-hostname #f]
+                                      [_local-port-no #f])
+      (error 'tcp-connect/enable-break "not supported"))
+
+    (define (tcp-listen _port-no
+                        [_backlog 4]
+                        [_reuse? #f]
+                        [_hostname #f])
+      (place-tcp-listener))
+
+    (define (tcp-listener? l)
+      (place-tcp-listener? l))))

+ 8 - 7
frameworks/Racket/racket/racket.dockerfile

@@ -11,14 +11,14 @@ RUN echo 'APT::Get::Install-Recommends "false";' > /etc/apt/apt.conf.d/00-genera
 
 FROM debian AS racket
 
-ARG RACKET_VERSION=8.1
+ARG RACKET_VERSION=8.3
 
 RUN apt-get update -q \
     && apt-get install --no-install-recommends -q -y \
          ca-certificates curl libcurl3-gnutls \
     && rm -rf /var/lib/apt/lists/* \
     && curl -L -o racket-install.sh \
-         -O http://mirror.racket-lang.org/installers/${RACKET_VERSION}/racket-minimal-${RACKET_VERSION}-x86_64-linux-cs.sh \
+         -O http://mirror.racket-lang.org/installers/${RACKET_VERSION}/racket-${RACKET_VERSION}-x86_64-linux-cs.sh \
     && echo "yes\n1\n" | sh racket-install.sh --create-dir --unix-style --dest /usr/ \
     && rm racket-install.sh
 
@@ -26,18 +26,19 @@ ENV SSL_CERT_FILE="/etc/ssl/certs/ca-certificates.crt"
 ENV SSL_CERT_DIR="/etc/ssl/certs"
 
 RUN apt-get update -q \
-  && apt-get install --no-install-recommends -q -y nginx redis-server
+  && apt-get install --no-install-recommends -q -y redis-server
 
 
 FROM racket AS builder
 
-RUN raco pkg install -D --auto compiler-lib db-lib redis-lib threading-lib unix-socket-lib web-server-lib
+RUN raco pkg install -D --auto --skip-installed redis-lib threading-lib
 
 WORKDIR /racket
 ADD  . .
 
-RUN raco make app.rkt \
-  && raco exe app.rkt
+RUN raco make main.rkt \
+    && raco exe -o app main.rkt \
+    && raco dist dist app
 
 
 FROM racket
@@ -46,7 +47,7 @@ RUN apt-get update -q \
   && apt-get install --no-install-recommends -q -y gettext-base
 
 WORKDIR /racket
-COPY --from=builder /racket/app .
+COPY --from=builder /racket/dist .
 ADD config config
 ADD scripts scripts
 

+ 1 - 34
frameworks/Racket/racket/scripts/run

@@ -6,37 +6,4 @@ echo never > /sys/kernel/mm/transparent_hugepage/enabled
 redis-server /racket/config/redis.conf &
 
 export PLT_INCREMENTAL_GC=1
-
-CORES=$(("$(nproc --all)" * 1))
-CONF="/racket/config/upstream.conf"
-
-cat >"$CONF" <<EOF
-upstream app {
-  least_conn;
-EOF
-
-for i in $(seq 0 $CORES); do
-    port=$((8081 + i))
-    /racket/app "$port" &
-    echo "  server unix:///racket/$port.sock;" >> "$CONF"
-done
-
-cat >>"$CONF" <<EOF
-  keepalive 512;
-}
-EOF
-
-for i in $(seq 0 $CORES); do
-    port=$((8081 + i))
-    filename="/racket/$port.ready"
-    while [ ! -f "$filename" ]; do
-        echo "Waiting for $filename..."
-        sleep 0.25;
-    done
-    chmod 0777 "/racket/$port.sock"
-done
-
-export NGINX_WORKER_PROCESES=$(("$CORES" / 4))
-envsubst '$NGINX_WORKER_PROCESES' < /racket/config/nginx.conf.tpl > /racket/config/nginx.conf
-cat /racket/config/upstream.conf
-nginx -c /racket/config/nginx.conf
+/racket/bin/app --host 0.0.0.0 --port 8080

+ 1 - 0
frameworks/Ruby/rails/.ruby-version

@@ -0,0 +1 @@
+3.1.0

+ 2 - 2
frameworks/Ruby/rails/Gemfile

@@ -1,4 +1,4 @@
-ruby '~> 3.0.0'
+ruby '~> 3.1.0'
 
 source 'https://rubygems.org'
 
@@ -7,6 +7,6 @@ gem 'mysql2', '0.5.3', group: :mysql
 gem 'oj', '~> 3.13'
 gem 'pg', '1.2.3', group: :postgresql
 gem 'puma', '~> 5.5'
-gem 'rails', '~> 6.1.3'
+gem 'rails', '~> 7.0.1'
 gem 'redis', '~> 4.0'
 gem 'tzinfo-data', '1.2021.5'

+ 94 - 82
frameworks/Ruby/rails/Gemfile.lock

@@ -1,78 +1,86 @@
 GEM
   remote: https://rubygems.org/
   specs:
-    actioncable (6.1.4.1)
-      actionpack (= 6.1.4.1)
-      activesupport (= 6.1.4.1)
+    actioncable (7.0.1)
+      actionpack (= 7.0.1)
+      activesupport (= 7.0.1)
       nio4r (~> 2.0)
       websocket-driver (>= 0.6.1)
-    actionmailbox (6.1.4.1)
-      actionpack (= 6.1.4.1)
-      activejob (= 6.1.4.1)
-      activerecord (= 6.1.4.1)
-      activestorage (= 6.1.4.1)
-      activesupport (= 6.1.4.1)
+    actionmailbox (7.0.1)
+      actionpack (= 7.0.1)
+      activejob (= 7.0.1)
+      activerecord (= 7.0.1)
+      activestorage (= 7.0.1)
+      activesupport (= 7.0.1)
       mail (>= 2.7.1)
-    actionmailer (6.1.4.1)
-      actionpack (= 6.1.4.1)
-      actionview (= 6.1.4.1)
-      activejob (= 6.1.4.1)
-      activesupport (= 6.1.4.1)
+      net-imap
+      net-pop
+      net-smtp
+    actionmailer (7.0.1)
+      actionpack (= 7.0.1)
+      actionview (= 7.0.1)
+      activejob (= 7.0.1)
+      activesupport (= 7.0.1)
       mail (~> 2.5, >= 2.5.4)
+      net-imap
+      net-pop
+      net-smtp
       rails-dom-testing (~> 2.0)
-    actionpack (6.1.4.1)
-      actionview (= 6.1.4.1)
-      activesupport (= 6.1.4.1)
-      rack (~> 2.0, >= 2.0.9)
+    actionpack (7.0.1)
+      actionview (= 7.0.1)
+      activesupport (= 7.0.1)
+      rack (~> 2.0, >= 2.2.0)
       rack-test (>= 0.6.3)
       rails-dom-testing (~> 2.0)
       rails-html-sanitizer (~> 1.0, >= 1.2.0)
-    actiontext (6.1.4.1)
-      actionpack (= 6.1.4.1)
-      activerecord (= 6.1.4.1)
-      activestorage (= 6.1.4.1)
-      activesupport (= 6.1.4.1)
+    actiontext (7.0.1)
+      actionpack (= 7.0.1)
+      activerecord (= 7.0.1)
+      activestorage (= 7.0.1)
+      activesupport (= 7.0.1)
+      globalid (>= 0.6.0)
       nokogiri (>= 1.8.5)
-    actionview (6.1.4.1)
-      activesupport (= 6.1.4.1)
+    actionview (7.0.1)
+      activesupport (= 7.0.1)
       builder (~> 3.1)
       erubi (~> 1.4)
       rails-dom-testing (~> 2.0)
       rails-html-sanitizer (~> 1.1, >= 1.2.0)
-    activejob (6.1.4.1)
-      activesupport (= 6.1.4.1)
+    activejob (7.0.1)
+      activesupport (= 7.0.1)
       globalid (>= 0.3.6)
-    activemodel (6.1.4.1)
-      activesupport (= 6.1.4.1)
-    activerecord (6.1.4.1)
-      activemodel (= 6.1.4.1)
-      activesupport (= 6.1.4.1)
-    activestorage (6.1.4.1)
-      actionpack (= 6.1.4.1)
-      activejob (= 6.1.4.1)
-      activerecord (= 6.1.4.1)
-      activesupport (= 6.1.4.1)
-      marcel (~> 1.0.0)
+    activemodel (7.0.1)
+      activesupport (= 7.0.1)
+    activerecord (7.0.1)
+      activemodel (= 7.0.1)
+      activesupport (= 7.0.1)
+    activestorage (7.0.1)
+      actionpack (= 7.0.1)
+      activejob (= 7.0.1)
+      activerecord (= 7.0.1)
+      activesupport (= 7.0.1)
+      marcel (~> 1.0)
       mini_mime (>= 1.1.0)
-    activesupport (6.1.4.1)
+    activesupport (7.0.1)
       concurrent-ruby (~> 1.0, >= 1.0.2)
       i18n (>= 1.6, < 2)
       minitest (>= 5.1)
       tzinfo (~> 2.0)
-      zeitwerk (~> 2.3)
     builder (3.2.4)
     concurrent-ruby (1.1.9)
     crass (1.0.6)
+    digest (3.1.0)
     erubi (1.10.0)
-    ffi (1.15.4)
+    ffi (1.15.5)
     globalid (1.0.0)
       activesupport (>= 5.0)
     i18n (1.8.11)
       concurrent-ruby (~> 1.0)
-    listen (3.7.0)
+    io-wait (0.2.1)
+    listen (3.7.1)
       rb-fsevent (~> 0.10, >= 0.10.3)
       rb-inotify (~> 0.9, >= 0.9.10)
-    loofah (2.12.0)
+    loofah (2.13.0)
       crass (~> 1.0.2)
       nokogiri (>= 1.5.9)
     mail (2.7.1)
@@ -80,18 +88,27 @@ GEM
     marcel (1.0.2)
     method_source (1.0.0)
     mini_mime (1.1.2)
-    mini_portile2 (2.6.1)
-    minitest (5.14.4)
+    minitest (5.15.0)
     mysql2 (0.5.3)
+    net-imap (0.2.3)
+      digest
+      net-protocol
+      strscan
+    net-pop (0.1.1)
+      digest
+      net-protocol
+      timeout
+    net-protocol (0.1.2)
+      io-wait
+      timeout
+    net-smtp (0.3.1)
+      digest
+      net-protocol
+      timeout
     nio4r (2.5.8)
-    nokogiri (1.12.5)
-      mini_portile2 (~> 2.6.1)
+    nokogiri (1.13.1-arm64-darwin)
       racc (~> 1.4)
-    nokogiri (1.12.5-arm64-darwin)
-      racc (~> 1.4)
-    nokogiri (1.12.5-x86_64-linux)
-      racc (~> 1.4)
-    oj (3.13.9)
+    oj (3.13.11)
     pg (1.2.3)
     puma (5.5.2)
       nio4r (~> 2.0)
@@ -99,45 +116,40 @@ GEM
     rack (2.2.3)
     rack-test (1.1.0)
       rack (>= 1.0, < 3)
-    rails (6.1.4.1)
-      actioncable (= 6.1.4.1)
-      actionmailbox (= 6.1.4.1)
-      actionmailer (= 6.1.4.1)
-      actionpack (= 6.1.4.1)
-      actiontext (= 6.1.4.1)
-      actionview (= 6.1.4.1)
-      activejob (= 6.1.4.1)
-      activemodel (= 6.1.4.1)
-      activerecord (= 6.1.4.1)
-      activestorage (= 6.1.4.1)
-      activesupport (= 6.1.4.1)
+    rails (7.0.1)
+      actioncable (= 7.0.1)
+      actionmailbox (= 7.0.1)
+      actionmailer (= 7.0.1)
+      actionpack (= 7.0.1)
+      actiontext (= 7.0.1)
+      actionview (= 7.0.1)
+      activejob (= 7.0.1)
+      activemodel (= 7.0.1)
+      activerecord (= 7.0.1)
+      activestorage (= 7.0.1)
+      activesupport (= 7.0.1)
       bundler (>= 1.15.0)
-      railties (= 6.1.4.1)
-      sprockets-rails (>= 2.0.0)
+      railties (= 7.0.1)
     rails-dom-testing (2.0.3)
       activesupport (>= 4.2.0)
       nokogiri (>= 1.6)
     rails-html-sanitizer (1.4.2)
       loofah (~> 2.3)
-    railties (6.1.4.1)
-      actionpack (= 6.1.4.1)
-      activesupport (= 6.1.4.1)
+    railties (7.0.1)
+      actionpack (= 7.0.1)
+      activesupport (= 7.0.1)
       method_source
-      rake (>= 0.13)
+      rake (>= 12.2)
       thor (~> 1.0)
+      zeitwerk (~> 2.5)
     rake (13.0.6)
     rb-fsevent (0.11.0)
     rb-inotify (0.10.1)
       ffi (~> 1.0)
     redis (4.5.1)
-    sprockets (4.0.2)
-      concurrent-ruby (~> 1.0)
-      rack (> 1, < 3)
-    sprockets-rails (3.4.1)
-      actionpack (>= 5.2)
-      activesupport (>= 5.2)
-      sprockets (>= 3.0.0)
-    thor (1.1.0)
+    strscan (3.0.1)
+    thor (1.2.1)
+    timeout (0.2.0)
     tzinfo (2.0.4)
       concurrent-ruby (~> 1.0)
     tzinfo-data (1.2021.5)
@@ -145,7 +157,7 @@ GEM
     websocket-driver (0.7.5)
       websocket-extensions (>= 0.1.0)
     websocket-extensions (0.1.5)
-    zeitwerk (2.5.1)
+    zeitwerk (2.5.3)
 
 PLATFORMS
   arm64-darwin-20
@@ -158,12 +170,12 @@ DEPENDENCIES
   oj (~> 3.13)
   pg (= 1.2.3)
   puma (~> 5.5)
-  rails (~> 6.1.3)
+  rails (~> 7.0.1)
   redis (~> 4.0)
   tzinfo-data (= 1.2021.5)
 
 RUBY VERSION
-   ruby 3.0.0p0
+   ruby 3.1.0p0
 
 BUNDLED WITH
-   2.2.22
+   2.3.3

+ 6 - 6
frameworks/Ruby/rails/README.md

@@ -12,12 +12,12 @@ comparing a variety of web platforms.
 
 The tests were run with:
 
-- [Ruby 3.0.0](http://www.ruby-lang.org/)
-- [Rails 6.1.3](http://rubyonrails.org/)
-- [Puma 5.2.1](http://puma.io/)
-- [MySQL 5.5](https://dev.mysql.com/)
-- [PostgreSQL 11](https://www.postgresql.org/)
-- [Redis 5.0](https://redis.io)
+- [Ruby 3.1.0](http://www.ruby-lang.org/)
+- [Rails 7.0.1](http://rubyonrails.org/)
+- [Puma 5.5](http://puma.io/)
+- [MySQL](https://dev.mysql.com/)
+- [PostgreSQL](https://www.postgresql.org/)
+- [Redis 6](https://redis.io)
 ## Paths & Source for Tests
 
 - [JSON Serialization](app/controllers/hello_world_controller.rb): "/json"

+ 1 - 1
frameworks/Ruby/rails/app/models/application_record.rb

@@ -1,3 +1,3 @@
 class ApplicationRecord < ActiveRecord::Base
-  self.abstract_class = true
+  primary_abstract_class
 end

+ 1 - 1
frameworks/Ruby/rails/bin/rails

@@ -1,4 +1,4 @@
 #!/usr/bin/env ruby
-APP_PATH = File.expand_path('../config/application', __dir__)
+APP_PATH = File.expand_path("../config/application", __dir__)
 require_relative "../config/boot"
 require "rails/commands"

+ 1 - 1
frameworks/Ruby/rails/config/application.rb

@@ -20,7 +20,7 @@ Bundler.require(*Rails.groups)
 module Hello
   class Application < Rails::Application
     # Initialize configuration defaults for originally generated Rails version.
-    config.load_defaults 6.1
+    config.load_defaults 7.0
 
     # Settings in config/environments/* take precedence over those specified here.
     # Application configuration can go into files in config/initializers

+ 1 - 1
frameworks/Ruby/rails/config/boot.rb

@@ -1,3 +1,3 @@
-ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
+ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
 
 require "bundler/setup" # Set up gems listed in the Gemfile.

+ 15 - 6
frameworks/Ruby/rails/config/environments/development.rb

@@ -14,15 +14,18 @@ Rails.application.configure do
   # Show full error reports.
   config.consider_all_requests_local = true
 
+  # Enable server timing
+  config.server_timing = true
+
   # Enable/disable caching. By default caching is disabled.
   # Run rails dev:cache to toggle caching.
-  if Rails.root.join('tmp', 'caching-dev.txt').exist?
+  if Rails.root.join("tmp/caching-dev.txt").exist?
     config.action_controller.perform_caching = true
     config.action_controller.enable_fragment_cache_logging = true
 
     config.cache_store = :memory_store
     config.public_file_server.headers = {
-      'Cache-Control' => "public, max-age=#{2.days.to_i}"
+      "Cache-Control" => "public, max-age=#{2.days.to_i}"
     }
   else
     config.action_controller.perform_caching = false
@@ -45,10 +48,16 @@ Rails.application.configure do
   # Highlight code that triggered database queries in logs.
   config.active_record.verbose_query_logs = true
 
-  # Use an evented file watcher to asynchronously detect changes in source code,
-  # routes, locales, etc. This feature depends on the listen gem.
-  config.file_watcher = ActiveSupport::EventedFileUpdateChecker
+
+  # Raises error for missing translations.
+  # config.i18n.raise_on_missing_translations = true
+
+  # Annotate rendered view with file names.
+  # config.action_view.annotate_rendered_view_with_filenames = true
 
   # Uncomment if you wish to allow Action Cable access from any origin.
   # config.action_cable.disable_request_forgery_protection = true
-end
+
+  # Raise error when a before_action's only/except options reference missing actions
+  config.action_controller.raise_on_missing_callback_actions = true
+end

+ 25 - 13
frameworks/Ruby/rails/config/environments/production.rb

@@ -16,9 +16,23 @@ Rails.application.configure do
   config.consider_all_requests_local       = false
   config.action_controller.perform_caching = true
 
+  # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
+  # or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
+  # config.require_master_key = true
+
   # Disable serving static files from the `/public` folder by default since
   # Apache or NGINX already handles this.
-  config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
+  config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present?
+
+  # Enable serving of images, stylesheets, and JavaScripts from an asset server.
+  # config.asset_host = "http://assets.example.com"
+
+  # Specifies the header that your server uses for sending files.
+  # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
+  # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX
+
+  # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
+  # config.force_ssl = true
 
   # Include generic and useful information about system operation, but avoid logging too much
   # information to avoid inadvertent exposure of personally identifiable information (PII).
@@ -28,37 +42,35 @@ Rails.application.configure do
   config.log_tags = [ :request_id ]
 
   # Use a different cache store in production.
-  config.cache_store = :redis_cache_store, { 
+  config.cache_store = :redis_cache_store, {
     url: ENV['REDIS_URL'],
     connect_timeout:    30,  # Defaults to 20 seconds
     read_timeout:       0.2, # Defaults to 1 second
     write_timeout:      0.2, # Defaults to 1 second
     reconnect_attempts: 1,   # Defaults to 0
-  
+
     error_handler: -> (method:, returning:, exception:) {
       puts "NO REDIS DETECTED"
     }
   }
 
+  # Use a real queuing backend for Active Job (and separate queues per environment).
+  # config.active_job.queue_adapter     = :resque
+  # config.active_job.queue_name_prefix = "hello_production"
+
   # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
   # the I18n.default_locale when a translation cannot be found).
   config.i18n.fallbacks = true
 
-  # Send deprecation notices to registered listeners.
-  config.active_support.deprecation = :notify
-
-  # Log disallowed deprecations.
-  config.active_support.disallowed_deprecation = :log
-
-  # Tell Active Support which deprecation messages to disallow.
-  config.active_support.disallowed_deprecation_warnings = []
+  # Don't log any deprecations.
+  config.active_support.report_deprecations = false
 
   # Use default logging formatter so that PID and timestamp are not suppressed.
   config.log_formatter = ::Logger::Formatter.new
 
   # Use a different logger for distributed setups.
   # require "syslog/logger"
-  # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
+  # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new "app-name")
 
   if ENV["RAILS_LOG_TO_STDOUT"].present?
     logger           = ActiveSupport::Logger.new(STDOUT)
@@ -68,4 +80,4 @@ Rails.application.configure do
 
   # Do not dump schema after migrations.
   config.active_record.dump_schema_after_migration = false
-end
+end

+ 17 - 8
frameworks/Ruby/rails/config/environments/test.rb

@@ -8,18 +8,18 @@ require "active_support/core_ext/integer/time"
 Rails.application.configure do
   # Settings specified here will take precedence over those in config/application.rb.
 
-  config.cache_classes = false
-  config.action_view.cache_template_loading = true
+  # Turn false under Spring and add config.action_view.cache_template_loading = true.
+  config.cache_classes = true
 
-  # Do not eager load code on boot. This avoids loading your whole application
-  # just for the purpose of running a single test. If you are using a tool that
-  # preloads Rails for running tests, you may have to set it to true.
-  config.eager_load = false
+  # Eager loading loads your whole application. When running a single test locally,
+  # this probably isn't necessary. It's a good idea to do in a continuous integration
+  # system, or in some way before deploying your code.
+  config.eager_load = ENV["CI"].present?
 
   # Configure public file server for tests with Cache-Control for performance.
   config.public_file_server.enabled = true
   config.public_file_server.headers = {
-    'Cache-Control' => "public, max-age=#{1.hour.to_i}"
+    "Cache-Control" => "public, max-age=#{1.hour.to_i}"
   }
 
   # Show full error reports and disable caching.
@@ -41,4 +41,13 @@ Rails.application.configure do
 
   # Tell Active Support which deprecation messages to disallow.
   config.active_support.disallowed_deprecation_warnings = []
-end
+
+  # Raises error for missing translations.
+  # config.i18n.raise_on_missing_translations = true
+
+  # Annotate rendered view with file names.
+  # config.action_view.annotate_rendered_view_with_filenames = true
+
+  # Raise error when a before_action's only/except options reference missing actions
+  config.action_controller.raise_on_missing_callback_actions = true
+end

+ 2 - 2
frameworks/Ruby/rails/config/initializers/filter_parameter_logging.rb

@@ -2,5 +2,5 @@
 
 # Configure sensitive parameters which will be filtered from the log file.
 Rails.application.config.filter_parameters += [
-    :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
-]
+  :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
+]

+ 2 - 1
frameworks/Ruby/rails/rails-mysql.dockerfile

@@ -1,4 +1,4 @@
-FROM ruby:3.0
+FROM ruby:3.1
 
 RUN apt-get update -yqq && apt-get install -yqq --no-install-recommends redis-server
 
@@ -13,6 +13,7 @@ RUN bundle install --jobs=8
 
 COPY . /rails/
 
+ENV RUBY_YJIT_ENABLE=1
 ENV RAILS_ENV=production_mysql
 ENV PORT=8080
 ENV REDIS_URL=redis://localhost:6379/0/cache

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

@@ -1,4 +1,4 @@
-FROM ruby:3.0
+FROM ruby:3.1
 
 RUN apt-get update -yqq && apt-get install -yqq --no-install-recommends redis-server
 
@@ -13,6 +13,7 @@ RUN bundle install --jobs=8
 
 COPY . /rails/
 
+ENV RUBY_YJIT_ENABLE=1
 ENV RAILS_ENV=production_postgresql
 ENV PORT=8080
 ENV REDIS_URL=redis://localhost:6379/0/cache

+ 8 - 4
frameworks/Rust/ntex/Cargo.toml

@@ -37,12 +37,12 @@ tokio = ["ntex/tokio"]
 async-std = ["ntex/async-std"]
 
 [dependencies]
-ntex = { version = "0.5.0", default-features = false }
+ntex = "0.5.8"
 mimalloc = { version = "0.1.25", default-features = false }
 snmalloc-rs = { version = "0.2.26", features = ["1mib", "native-cpu"] }
 yarte = { version = "0.15", features = ["bytes-buf", "json"] }
-env_logger = "0.8"
-nanorand = { version = "0.5", default-features = false, features = ["std", "wyrand"] }
+env_logger = "0.9"
+nanorand = { version = "0.6", default-features = false, features = ["std", "wyrand"] }
 atoi = "0.4"
 num_cpus = "1.13"
 futures = "0.3"
@@ -56,6 +56,10 @@ log = { version = "0.4", features = ["release_max_level_off"] }
 tokio-postgres = { git="https://github.com/fafhrd91/postgres.git" }
 
 [profile.release]
-lto = true
 opt-level = 3
 codegen-units = 1
+panic = 'abort'
+lto = "thin"
+debug = false
+incremental = false
+overflow-checks = false

+ 18 - 20
frameworks/Rust/ntex/src/db.rs

@@ -1,8 +1,8 @@
-use std::{borrow::Cow, cell::RefCell, fmt::Write as FmtWrite};
+use std::{borrow::Cow, fmt::Write as FmtWrite};
 
 use futures::{Future, FutureExt};
-use nanorand::{WyRand, RNG};
-use ntex::util::{Bytes, BytesMut};
+use nanorand::{WyRand, Rng};
+use ntex::util::{join_all, Bytes, BytesMut};
 use smallvec::SmallVec;
 use tokio_postgres::types::ToSql;
 use tokio_postgres::{connect, Client, Statement};
@@ -30,7 +30,7 @@ pub struct PgConnection {
     cl: Client,
     fortune: Statement,
     world: Statement,
-    rng: RefCell<WyRand>,
+    rng: WyRand,
     updates: Vec<Statement>,
 }
 
@@ -67,14 +67,14 @@ impl PgConnection {
             fortune,
             world,
             updates,
-            rng: RefCell::new(WyRand::new()),
+            rng: WyRand::new(),
         }
     }
 }
 
 impl PgConnection {
     pub fn get_world(&self) -> impl Future<Output = Bytes> {
-        let random_id = (self.rng.borrow_mut().generate::<u32>() % 10_000 + 1) as i32;
+        let random_id = (self.rng.clone().generate::<u32>() % 10_000 + 1) as i32;
         self.cl.query(&self.world, &[&random_id]).map(|rows| {
             let rows = rows.unwrap();
             let mut body = BytesMut::new();
@@ -92,7 +92,7 @@ impl PgConnection {
 
     pub fn get_worlds(&self, num: u16) -> impl Future<Output = Vec<World>> {
         let mut futs = Vec::with_capacity(num as usize);
-        let mut rng = self.rng.borrow_mut();
+        let mut rng = self.rng.clone();
         for _ in 0..num {
             let w_id = (rng.generate::<u32>() % 10_000 + 1) as i32;
             futs.push(self.cl.query(&self.world, &[&w_id]));
@@ -100,8 +100,8 @@ impl PgConnection {
 
         async move {
             let mut worlds: Vec<World> = Vec::with_capacity(num as usize);
-            for q in futs {
-                let rows = q.await.unwrap();
+            for item in join_all(futs).await {
+                let rows = item.unwrap();
                 worlds.push(World {
                     id: rows[0].get(0),
                     randomnumber: rows[0].get(1),
@@ -113,25 +113,23 @@ impl PgConnection {
 
     pub fn update(&self, num: u16) -> impl Future<Output = Vec<World>> {
         let mut futs = Vec::with_capacity(num as usize);
-        let mut rng = self.rng.borrow_mut();
+        let mut rng = self.rng.clone();
         for _ in 0..num {
-            let id = (rng.generate::<u32>() % 10_000 + 1) as i32;
             let w_id = (rng.generate::<u32>() % 10_000 + 1) as i32;
-            futs.push(self.cl.query(&self.world, &[&w_id]).map(move |res| {
-                let rows = res.unwrap();
-                World {
-                    id: rows[0].get(0),
-                    randomnumber: id,
-                }
-            }));
+            futs.push(self.cl.query(&self.world, &[&w_id]));
         }
 
         let cl = self.cl.clone();
         let st = self.updates[(num as usize) - 1].clone();
         async move {
             let mut worlds: Vec<World> = Vec::with_capacity(num as usize);
-            for q in futs {
-                worlds.push(q.await);
+            for q in join_all(futs).await {
+                let q = q.unwrap();
+                let id = (rng.generate::<u32>() % 10_000 + 1) as i32;
+                worlds.push(World {
+                    id: q[0].get(0),
+                    randomnumber: id,
+                })
             }
 
             let mut params: Vec<&dyn ToSql> = Vec::with_capacity(num as usize * 3);

+ 18 - 14
frameworks/Rust/ntex/src/main.rs

@@ -1,8 +1,8 @@
 #[global_allocator]
 static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
 
-use ntex::http::header::{HeaderValue, CONTENT_TYPE, SERVER};
-use ntex::{http, time::Seconds, util::Bytes, util::PoolId, web};
+use ntex::http::header::{CONTENT_TYPE, SERVER};
+use ntex::{http, time::Seconds, util::PoolId, web};
 use yarte::Serialize;
 
 mod utils;
@@ -20,18 +20,25 @@ async fn json() -> web::HttpResponse {
     }
     .to_bytes_mut(&mut body);
 
-    web::HttpResponse::Ok()
-        .header(SERVER, HeaderValue::from_static("N"))
-        .header(CONTENT_TYPE, HeaderValue::from_static("application/json"))
-        .body(body)
+    let mut response = web::HttpResponse::with_body(http::StatusCode::OK, body.into());
+    response.headers_mut().append(SERVER, utils::HDR_SERVER);
+    response
+        .headers_mut()
+        .append(CONTENT_TYPE, utils::HDR_JSON_CONTENT_TYPE);
+    response
 }
 
 #[web::get("/plaintext")]
 async fn plaintext() -> web::HttpResponse {
-    web::HttpResponse::Ok()
-        .header(SERVER, HeaderValue::from_static("N"))
-        .header(CONTENT_TYPE, HeaderValue::from_static("text/plain"))
-        .body(Bytes::from_static(b"Hello, World!"))
+    let mut response = web::HttpResponse::with_body(
+        http::StatusCode::OK,
+        http::body::Body::Bytes(utils::BODY_PLAIN_TEXT),
+    );
+    response.headers_mut().append(SERVER, utils::HDR_SERVER);
+    response
+        .headers_mut()
+        .append(CONTENT_TYPE, utils::HDR_TEXT_CONTENT_TYPE);
+    response
 }
 
 #[ntex::main]
@@ -49,10 +56,7 @@ async fn main() -> std::io::Result<()> {
             http::HttpService::build()
                 .keep_alive(http::KeepAlive::Os)
                 .client_timeout(Seconds(0))
-                .h1(web::App::new()
-                    .service(json)
-                    .service(plaintext)
-                    .with_config(web::dev::AppConfig::default()))
+                .h1(web::App::new().service(json).service(plaintext).finish())
         })?
         .run()
         .await

+ 21 - 20
frameworks/Rust/ntex/src/main_db.rs

@@ -4,7 +4,7 @@ static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
 use std::{pin::Pin, task::Context, task::Poll};
 
 use futures::future::{ok, Future, FutureExt};
-use ntex::http::header::{HeaderValue, CONTENT_TYPE, SERVER};
+use ntex::http::header::{CONTENT_TYPE, SERVER};
 use ntex::http::{HttpService, KeepAlive, Request, Response};
 use ntex::service::{Service, ServiceFactory};
 use ntex::web::{Error, HttpResponse};
@@ -31,19 +31,18 @@ impl Service<Request> for App {
     fn call(&self, req: Request) -> Self::Future {
         match req.path() {
             "/db" => Box::pin(self.0.get_world().map(|body| {
-                Ok(HttpResponse::Ok()
-                    .header(SERVER, HeaderValue::from_static("N"))
-                    .header(CONTENT_TYPE, HeaderValue::from_static("application/json"))
-                    .body(body))
+                let mut res = HttpResponse::with_body(http::StatusCode::OK, body.into());
+                res.headers_mut().append(SERVER, utils::HDR_SERVER);
+                res.headers_mut()
+                    .append(CONTENT_TYPE, utils::HDR_JSON_CONTENT_TYPE);
+                Ok(res)
             })),
             "/fortunes" => Box::pin(self.0.tell_fortune().map(|body| {
-                Ok(HttpResponse::Ok()
-                    .header(SERVER, HeaderValue::from_static("N"))
-                    .header(
-                        CONTENT_TYPE,
-                        HeaderValue::from_static("text/html; charset=utf-8"),
-                    )
-                    .body(body))
+                let mut res = HttpResponse::with_body(http::StatusCode::OK, body.into());
+                res.headers_mut().append(SERVER, utils::HDR_SERVER);
+                res.headers_mut()
+                    .append(CONTENT_TYPE, utils::HDR_HTML_CONTENT_TYPE);
+                Ok(res)
             })),
             "/query" => Box::pin(
                 self.0
@@ -51,10 +50,11 @@ impl Service<Request> for App {
                     .map(|worlds| {
                         let mut body = BytesMut::with_capacity(35 * worlds.len());
                         let _ = simd_json::to_writer(crate::utils::Writer(&mut body), &worlds);
-                        Ok(HttpResponse::Ok()
-                            .header(SERVER, HeaderValue::from_static("N"))
-                            .header(CONTENT_TYPE, HeaderValue::from_static("application/json"))
-                            .body(body.freeze()))
+                        let mut res = HttpResponse::with_body(http::StatusCode::OK, body.into());
+                        res.headers_mut().append(SERVER, utils::HDR_SERVER);
+                        res.headers_mut()
+                            .append(CONTENT_TYPE, utils::HDR_JSON_CONTENT_TYPE);
+                        Ok(res)
                     }),
             ),
             "/update" => Box::pin(
@@ -63,10 +63,11 @@ impl Service<Request> for App {
                     .map(|worlds| {
                         let mut body = BytesMut::with_capacity(35 * worlds.len());
                         let _ = simd_json::to_writer(crate::utils::Writer(&mut body), &worlds);
-                        Ok(HttpResponse::Ok()
-                            .header(SERVER, HeaderValue::from_static("N"))
-                            .header(CONTENT_TYPE, HeaderValue::from_static("application/json"))
-                            .body(body.freeze()))
+                        let mut res = HttpResponse::with_body(http::StatusCode::OK, body.into());
+                        res.headers_mut().append(SERVER, utils::HDR_SERVER);
+                        res.headers_mut()
+                            .append(CONTENT_TYPE, utils::HDR_JSON_CONTENT_TYPE);
+                        Ok(res)
                     }),
             ),
             _ => Box::pin(ok(Response::new(http::StatusCode::NOT_FOUND))),

+ 2 - 2
frameworks/Rust/ntex/src/main_plt.rs

@@ -86,8 +86,8 @@ async fn main() -> io::Result<()> {
         .backlog(1024)
         .bind("techempower", "0.0.0.0:8080", |cfg| {
             cfg.memory_pool(PoolId::P1);
-            PoolId::P1.set_read_params(65535, 8192);
-            PoolId::P1.set_write_params(65535, 8192);
+            PoolId::P1.set_read_params(65535, 1024);
+            PoolId::P1.set_write_params(65535, 1024);
 
             fn_service(|io| App {
                 io,

+ 9 - 1
frameworks/Rust/ntex/src/utils.rs

@@ -2,7 +2,15 @@
 use std::{cmp, io};
 
 use atoi::FromRadix10;
-use ntex::util::{BufMut, BytesMut};
+use ntex::http::header::HeaderValue;
+use ntex::util::{BufMut, Bytes, BytesMut};
+
+pub const HDR_SERVER: HeaderValue = HeaderValue::from_static("N");
+pub const HDR_JSON_CONTENT_TYPE: HeaderValue = HeaderValue::from_static("application/json");
+pub const HDR_TEXT_CONTENT_TYPE: HeaderValue = HeaderValue::from_static("text/plain");
+pub const HDR_HTML_CONTENT_TYPE: HeaderValue =
+    HeaderValue::from_static("text/html; charset=utf-8");
+pub const BODY_PLAIN_TEXT: Bytes = Bytes::from_static(b"Hello, World!");
 
 pub const SIZE: usize = 27;
 

+ 2 - 2
frameworks/Scala/finagle/build.sbt

@@ -1,4 +1,4 @@
-lazy val finagleVersion = "21.12.0"
+lazy val finagleVersion = "22.1.0"
 
 name := "finagle-benchmark"
 scalaVersion := "2.12.12"
@@ -6,7 +6,7 @@ version := finagleVersion
 
 libraryDependencies ++= Seq(
   "com.twitter" %% "finagle-http" % finagleVersion,
-  "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.11.2"
+  "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.13.1"
 )
 
 assemblyJarName in assembly := "finagle-benchmark.jar"

+ 2 - 2
frameworks/Scala/finatra/build.sbt

@@ -1,4 +1,4 @@
-lazy val finatraVersion = "21.12.0"
+lazy val finatraVersion = "22.1.0"
 
 name := "techempower-benchmarks-finatra"
 organization := "com.twitter"
@@ -21,7 +21,7 @@ libraryDependencies ++= Seq(
   ("com.twitter" %% "finatra-http-server" % finatraVersion).
     exclude("com.sun.activation", "javax.activation"),
   "org.slf4j" % "slf4j-nop" % "1.7.30",
-  "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.11.2",
+  "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.13.1",
 )
 
 excludeDependencies ++= Seq(