Pārlūkot izejas kodu

Unhinged - Add high worker variant (#10280)

* Add high worker variant

* bump unhinged to 9.0.7
Diogo Martins 1 mēnesi atpakaļ
vecāks
revīzija
13ff46a55a

+ 17 - 0
frameworks/CSharp/wiredio/benchmark_config.json

@@ -37,6 +37,23 @@
         "display_name": "Unhinged",
         "notes": "epoll"
       },
+      "mcr-p": {
+        "plaintext_url": "/plaintext",
+        "json_url": "/json",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "database": "None",
+        "framework": "Unhinged",
+        "language": "C#",
+        "orm": "None",
+        "platform": ".NET",
+        "webserver": "Unhinged",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "Unhinged [p]",
+        "notes": "epoll"
+      },
       "gen": {
         "plaintext_url": "/plaintext",
         "json_url": "/json",

+ 12 - 0
frameworks/CSharp/wiredio/config.toml

@@ -25,6 +25,18 @@ platform = ".NET"
 webserver = "Unhinged"
 versus = "None"
 
+[mcr-p]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+approach = "Realistic"
+classification = "Micro"
+os = "Linux"
+database_os = "Linux"
+orm = "None"
+platform = ".NET"
+webserver = "Unhinged"
+versus = "None"
+
 [gen]
 urls.plaintext = "/plaintext"
 urls.json = "/json"

+ 25 - 0
frameworks/CSharp/wiredio/src/PlatformP/Platform.csproj

@@ -0,0 +1,25 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+    <PropertyGroup>
+        <OutputType>Exe</OutputType>
+        <TargetFramework>net9.0</TargetFramework>
+        <ImplicitUsings>enable</ImplicitUsings>
+        <Nullable>enable</Nullable>
+        <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+        <IsTestAssetProject>true</IsTestAssetProject>
+        <ServerGarbageCollection>true</ServerGarbageCollection>
+        <TieredPGO>true</TieredPGO>
+
+        <!-- Required for self-contained publish -->
+        <RuntimeIdentifier>linux-musl-x64</RuntimeIdentifier>
+        <SelfContained>true</SelfContained>
+    </PropertyGroup>
+
+    <ItemGroup Condition="$(PublishAot) == 'true'">
+        <RuntimeHostConfigurationOption Include="System.Threading.ThreadPool.HillClimbing.Disable" Value="true" />
+    </ItemGroup>
+
+    <ItemGroup>
+      <PackageReference Include="Unhinged" Version="9.0.7" />
+    </ItemGroup>
+</Project>

+ 98 - 0
frameworks/CSharp/wiredio/src/PlatformP/Program.cs

@@ -0,0 +1,98 @@
+// ReSharper disable always SuggestVarOrType_BuiltInTypes
+// (var is avoided intentionally in this project so that concrete types are visible at call sites.)
+// ReSharper disable always StackAllocInsideLoop
+
+using System.Runtime.CompilerServices;
+using System.Text.Json;
+using Unhinged;
+
+#pragma warning disable CA2014
+
+/* (MDA2AV)Dev notes:
+ * 
+ * Wired.IO Platform benchmark using [Unhinged - https://github.com/MDA2AV/Unhinged] epoll engine.
+ *
+ * This test was created purely for benchmark/comparison between .NET solutions.
+ * It should not be considered EVER as a go-to framework to build any kind of webserver!
+ * For such purpose please use the main Wired.IO framework [Wired.IO - https://github.com/MDA2AV/Wired.IO].
+ *
+ * This benchmarks follows the JsonSerialization and PlainText rules imposed by the TechEmpower team.
+ *
+ * The Http parsing by the Unhinged engine is still naive(work in progress), yet it's development will not have any impact
+ * on these benchmarks results as the extra request parsing overhead is much smaller than the read/send syscalls'.
+ */
+
+namespace Platform;
+
+[SkipLocalsInit]
+internal static class Program
+{
+    public static void Main(string[] args)
+    {
+        var builder = UnhingedEngine
+            .CreateBuilder()
+            .SetPort(8080)
+            
+            .SetNWorkersSolver(() => Environment.ProcessorCount )  
+            
+            // Accept up to 16384 connections
+            .SetBacklog(16384) 
+            
+            // Max 512 epoll events per wake (quite overkill)
+            .SetMaxEventsPerWake(512)         
+            
+            // Max 1024 connection per thread
+            .SetMaxNumberConnectionsPerWorker(1024)
+            
+            // 32KB in and 16KB out slabs to handle 16 pipeline depth
+            .SetSlabSizes(32 * 1024, 16 * 1024)
+            .InjectRequestHandler(RequestHandler);
+        
+        var engine = builder.Build();
+        engine.Run();
+    }
+
+    private const string Json = "/json";
+    private const string PlainText = "/plaintext";
+
+    private static ValueTask RequestHandler(Connection connection)
+    {
+        // FNV-1a Hashed routes to avoid string allocations
+        if(connection.H1HeaderData.Route == Json)          // /json
+            CommitJsonResponse(connection);
+       
+        else if (connection.H1HeaderData.Route == PlainText)   // /plaintext
+            CommitPlainTextResponse(connection);
+        
+        return  ValueTask.CompletedTask;
+    }
+    
+    [ThreadStatic] private static Utf8JsonWriter? t_utf8JsonWriter;
+    private static readonly JsonContext SerializerContext = JsonContext.Default;
+    private static void CommitJsonResponse(Connection connection)
+    {
+        connection.WriteBuffer.WriteUnmanaged("HTTP/1.1 200 OK\r\n"u8 +
+                                              "Server: W\r\n"u8 +
+                                              "Content-Type: application/json; charset=UTF-8\r\n"u8 +
+                                              "Content-Length: 27\r\n"u8);
+        connection.WriteBuffer.WriteUnmanaged(DateHelper.HeaderBytes);
+        
+        t_utf8JsonWriter ??= new Utf8JsonWriter(connection.WriteBuffer, new JsonWriterOptions { SkipValidation = true });
+        t_utf8JsonWriter.Reset(connection.WriteBuffer);
+        
+        // Creating(Allocating) a new JsonMessage every request
+        var message = new JsonMessage { Message = "Hello, World!" };
+        // Serializing it every request
+        JsonSerializer.Serialize(t_utf8JsonWriter, message, SerializerContext.JsonMessage);
+    }
+
+    private static void CommitPlainTextResponse(Connection connection)
+    {
+        connection.WriteBuffer.WriteUnmanaged("HTTP/1.1 200 OK\r\n"u8 +
+                                              "Server: W\r\n"u8 +
+                                              "Content-Type: text/plain\r\n"u8 +
+                                              "Content-Length: 13\r\n"u8);
+        connection.WriteBuffer.WriteUnmanaged(DateHelper.HeaderBytes);
+        connection.WriteBuffer.WriteUnmanaged("Hello, World!"u8);
+    }
+}

+ 22 - 0
frameworks/CSharp/wiredio/wiredio-mcr-p.dockerfile

@@ -0,0 +1,22 @@
+# Build
+FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build
+RUN apk add --no-cache clang build-base zlib-dev linux-headers
+WORKDIR /src
+COPY src/PlatformP/ ./PlatformP/
+WORKDIR /src/PlatformP
+RUN dotnet publish -c Release \
+    -r linux-musl-x64 \
+    --self-contained true \
+    -p:PublishAot=true \
+    -p:OptimizationPreference=Speed \
+    -p:GarbageCollectionAdaptationMode=0 \
+    -o /app/out
+
+# Runtime (musl)
+FROM mcr.microsoft.com/dotnet/runtime-deps:9.0-alpine
+ENV URLS=http://+:8080
+WORKDIR /app
+COPY --from=build /app/out ./
+RUN chmod +x ./Platform
+EXPOSE 8080
+ENTRYPOINT ["./Platform"]