Skip to content

Commit 0323e1b

Browse files
committed
Bump Wired.IO to 9.5.0, supports pipelined http. Add platform benchmark
1 parent 269b91b commit 0323e1b

File tree

10 files changed

+250
-77
lines changed

10 files changed

+250
-77
lines changed

frameworks/CSharp/wiredio/Benchmarks/Benchmarks.csproj

Lines changed: 0 additions & 23 deletions
This file was deleted.

frameworks/CSharp/wiredio/Benchmarks/Program.cs

Lines changed: 0 additions & 32 deletions
This file was deleted.

frameworks/CSharp/wiredio/benchmark_config.json

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"framework": "wiredio",
3+
"maintainers": ["Diogo Martins"],
34
"tests": [
45
{
56
"default": {
@@ -17,7 +18,24 @@
1718
"os": "Linux",
1819
"database_os": "Linux",
1920
"display_name": "Wired.IO",
20-
"notes": "Only plaintext and JSON benchmarks implemented"
21+
"notes": "Only plaintext and JSON benchmarks implemented yet"
22+
},
23+
"plt": {
24+
"plaintext_url": "/plaintext",
25+
"json_url": "/json",
26+
"port": 8080,
27+
"approach": "Realistic",
28+
"classification": "Platform",
29+
"database": "None",
30+
"framework": "Unhinged",
31+
"language": "C#",
32+
"orm": "None",
33+
"platform": ".NET",
34+
"webserver": "Unhinged",
35+
"os": "Linux",
36+
"database_os": "Linux",
37+
"display_name": "Wired.IO [Unhinged]",
38+
"notes": "Not a framework"
2139
}
2240
}
2341
]

frameworks/CSharp/wiredio/config.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,15 @@ orm = "None"
1212
platform = ".NET"
1313
webserver = "Wired.IO"
1414
versus = "None"
15+
16+
[plt]
17+
urls.plaintext = "/plaintext"
18+
urls.json = "/json"
19+
approach = "Realistic"
20+
classification = "Platform"
21+
os = "Linux"
22+
database_os = "Linux"
23+
orm = "None"
24+
platform = ".NET"
25+
webserver = "Unhinged"
26+
versus = "None"
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net9.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
9+
<IsTestAssetProject>true</IsTestAssetProject>
10+
<ServerGarbageCollection>true</ServerGarbageCollection>
11+
<TieredPGO>true</TieredPGO>
12+
13+
<!-- Required for self-contained publish -->
14+
<RuntimeIdentifier>linux-musl-x64</RuntimeIdentifier>
15+
<SelfContained>true</SelfContained>
16+
</PropertyGroup>
17+
18+
<ItemGroup Condition="$(PublishAot) == 'true'">
19+
<RuntimeHostConfigurationOption Include="System.Threading.ThreadPool.HillClimbing.Disable" Value="true" />
20+
</ItemGroup>
21+
22+
<ItemGroup>
23+
<PackageReference Include="Wired.IO" Version="9.5.0" />
24+
</ItemGroup>
25+
26+
</Project>
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using System.IO.Pipelines;
2+
using System.Text.Json;
3+
using System.Text.Json.Serialization;
4+
using Wired.IO.App;
5+
6+
namespace Fullstack;
7+
8+
internal class Program
9+
{
10+
public static async Task Main(string[] args)
11+
{
12+
var expressBuilder = WiredApp.CreateExpressBuilder();
13+
14+
await expressBuilder
15+
.Port(8080)
16+
.MapGet("/json", scope => async ctx =>
17+
{
18+
var payload = new JsonMessage { Message = JsonBody };
19+
var myHandler = CreateBoundHandler(ctx.Writer, payload);
20+
21+
ctx
22+
.Respond()
23+
.Type("application/json"u8)
24+
.Content(myHandler, 27);
25+
26+
})
27+
.MapGet("/plaintext", scope => async ctx =>
28+
{
29+
ctx
30+
.Respond()
31+
.Type("application/json"u8)
32+
.Content(_plainTextBody);
33+
})
34+
.Build()
35+
.RunAsync();
36+
}
37+
38+
private static ReadOnlySpan<byte> _plainTextBody => "Hello, World!"u8;
39+
private const string JsonBody = "Hello, World!";
40+
41+
[ThreadStatic]
42+
private static Utf8JsonWriter? t_writer;
43+
private static readonly Action<PipeWriter, JsonMessage> StaticHandler = HandleFast;
44+
private static Action CreateBoundHandler(PipeWriter writer, JsonMessage message) => () => StaticHandler.Invoke(writer, message);
45+
private static void HandleFast(PipeWriter writer, JsonMessage message)
46+
{
47+
var utf8JsonWriter = t_writer ??= new Utf8JsonWriter(writer, new JsonWriterOptions { SkipValidation = true });
48+
utf8JsonWriter.Reset(writer);
49+
JsonSerializer.Serialize(utf8JsonWriter, message, SerializerContext.JsonMessage);
50+
}
51+
52+
private static readonly JsonContext SerializerContext = JsonContext.Default;
53+
}
54+
55+
public struct JsonMessage { public string Message { get; set; } }
56+
57+
[JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Serialization | JsonSourceGenerationMode.Metadata)]
58+
[JsonSerializable(typeof(JsonMessage))]
59+
public partial class JsonContext : JsonSerializerContext { }
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net9.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
9+
<IsTestAssetProject>true</IsTestAssetProject>
10+
<ServerGarbageCollection>true</ServerGarbageCollection>
11+
<TieredPGO>true</TieredPGO>
12+
13+
<!-- Required for self-contained publish -->
14+
<RuntimeIdentifier>linux-musl-x64</RuntimeIdentifier>
15+
<SelfContained>true</SelfContained>
16+
</PropertyGroup>
17+
18+
<ItemGroup Condition="$(PublishAot) == 'true'">
19+
<RuntimeHostConfigurationOption Include="System.Threading.ThreadPool.HillClimbing.Disable" Value="true" />
20+
</ItemGroup>
21+
22+
<ItemGroup>
23+
<PackageReference Include="Unhinged" Version="9.0.0" />
24+
</ItemGroup>
25+
</Project>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// ReSharper disable always SuggestVarOrType_BuiltInTypes
2+
// (var is avoided intentionally in this project so that concrete types are visible at call sites.)
3+
// ReSharper disable always StackAllocInsideLoop
4+
5+
using System.Runtime.CompilerServices;
6+
using System.Text.Json;
7+
using Unhinged;
8+
9+
#pragma warning disable CA2014
10+
11+
namespace Platform;
12+
13+
[SkipLocalsInit]
14+
internal static class Program
15+
{
16+
public static void Main(string[] args)
17+
{
18+
var builder = UnhingedEngine
19+
.CreateBuilder()
20+
.SetNWorkersSolver(() => Environment.ProcessorCount - 2) // Number of working threads, depends on a lot of things
21+
.SetBacklog(16384) // Accept up to 16384 connections
22+
.SetMaxEventsPerWake(512) // Max 512 epoll events per wake (quite overkill)
23+
.SetMaxNumberConnectionsPerWorker(512) // Max 512 connection per thread
24+
.SetPort(8080)
25+
.SetSlabSizes(32 * 1024, 32 * 1024) // 32KB slabs to handle high pipeline depth
26+
.InjectRequestHandler(RequestHandler);
27+
28+
var engine = builder.Build();
29+
30+
engine.Run();
31+
}
32+
33+
private static void RequestHandler(Connection connection)
34+
{
35+
// FNV-1a Hashed routes to avoid string allocations
36+
if(connection.HashedRoute == 291830056) // /json
37+
CommitJsonResponse(connection);
38+
39+
else if (connection.HashedRoute == 3454831873) // /plaintext
40+
CommitPlainTextResponse(connection);
41+
}
42+
43+
[ThreadStatic] private static Utf8JsonWriter? t_utf8JsonWriter;
44+
private static readonly JsonContext SerializerContext = JsonContext.Default;
45+
private static void CommitJsonResponse(Connection connection)
46+
{
47+
connection.WriteBuffer.WriteUnmanaged("HTTP/1.1 200 OK\r\n"u8 +
48+
"Server: W\r\n"u8 +
49+
"Content-Type: application/json; charset=UTF-8\r\n"u8 +
50+
"Content-Length: 27\r\n"u8);
51+
connection.WriteBuffer.WriteUnmanaged(DateHelper.HeaderBytes);
52+
53+
t_utf8JsonWriter ??= new Utf8JsonWriter(connection.WriteBuffer, new JsonWriterOptions { SkipValidation = true });
54+
t_utf8JsonWriter.Reset(connection.WriteBuffer);
55+
56+
// Creating(Allocating) a new JsonMessage every request
57+
var message = new JsonMessage { Message = "Hello, World!" };
58+
// Serializing it every request
59+
JsonSerializer.Serialize(t_utf8JsonWriter, message, SerializerContext.JsonMessage);
60+
}
61+
62+
private static void CommitPlainTextResponse(Connection connection)
63+
{
64+
connection.WriteBuffer.WriteUnmanaged("HTTP/1.1 200 OK\r\n"u8 +
65+
"Server: W\r\n"u8 +
66+
"Content-Type: text/plain\r\n"u8 +
67+
"Content-Length: 13\r\n"u8);
68+
connection.WriteBuffer.WriteUnmanaged(DateHelper.HeaderBytes);
69+
connection.WriteBuffer.WriteUnmanaged("Hello, World!"u8);
70+
}
71+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
2+
RUN apt-get update && apt-get install -y --no-install-recommends clang lld zlib1g-dev && rm -rf /var/lib/apt/lists/*
3+
WORKDIR /src
4+
COPY src/Platform/ ./Platform/
5+
WORKDIR /src/Platform
6+
RUN dotnet publish -c Release \
7+
-r linux-x64 \
8+
--self-contained true \
9+
-p:PublishAot=true \
10+
-p:OptimizationPreference=Speed \
11+
-p:GarbageCollectionAdaptationMode=0 \
12+
-o /app/out
13+
14+
FROM mcr.microsoft.com/dotnet/runtime-deps:9.0
15+
ENV URLS=http://+:8080
16+
WORKDIR /app
17+
COPY --from=build /app/out ./
18+
RUN chmod +x ./Platform
19+
EXPOSE 8080
20+
ENTRYPOINT ["./Platform"]
21+
Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,20 @@
1-
FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build
2-
WORKDIR /source
3-
4-
# copy csproj and restore as distinct layers
5-
COPY Benchmarks/*.csproj .
6-
RUN dotnet restore -r linux-musl-x64
7-
8-
# copy and publish app and libraries
9-
COPY Benchmarks/ .
10-
RUN dotnet publish -c release -o /app -r linux-musl-x64 --no-restore --self-contained
11-
12-
# final stage/image
13-
FROM mcr.microsoft.com/dotnet/runtime-deps:9.0-alpine
14-
15-
ENV DOTNET_GCDynamicAdaptationMode=0
16-
ENV DOTNET_ReadyToRun=0
17-
ENV DOTNET_HillClimbing_Disable=1
1+
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
2+
RUN apt-get update && apt-get install -y --no-install-recommends clang lld zlib1g-dev && rm -rf /var/lib/apt/lists/*
3+
WORKDIR /src
4+
COPY src/Fullstack/ ./Fullstack/
5+
WORKDIR /src/Fullstack
6+
RUN dotnet publish -c Release \
7+
-r linux-x64 \
8+
--self-contained true \
9+
-p:PublishAot=true \
10+
-p:OptimizationPreference=Speed \
11+
-p:GarbageCollectionAdaptationMode=0 \
12+
-o /app/out
1813

14+
FROM mcr.microsoft.com/dotnet/runtime-deps:9.0
15+
ENV URLS=http://+:8080
1916
WORKDIR /app
20-
COPY --from=build /app .
21-
22-
ENTRYPOINT ["./Benchmarks"]
23-
17+
COPY --from=build /app/out ./
18+
RUN chmod +x ./Fullstack
2419
EXPOSE 8080
20+
ENTRYPOINT ["./Fullstack"]

0 commit comments

Comments
 (0)