Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 0 additions & 23 deletions frameworks/CSharp/wiredio/Benchmarks/Benchmarks.csproj

This file was deleted.

32 changes: 0 additions & 32 deletions frameworks/CSharp/wiredio/Benchmarks/Program.cs

This file was deleted.

8 changes: 4 additions & 4 deletions frameworks/CSharp/wiredio/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ See the [Wired.IO Documentation](https://mda2av.github.io/Wired.IO.Docs/) for mo

**Platforms**

* .NET 8/9
* .NET 9

**Web Servers**

* [Wired.IO](https://github.com/MDA2AV/Wired.IO)

## Paths & Source for Tests
**Engines**

* [Plaintext](Benchmarks/Program.cs): "/plaintext"
* [JSON](Benchmarks/Program.cs): "/json"
* [Wired.IO](https://github.com/MDA2AV/Wired.IO)
* [Unhinged](https://github.com/MDA2AV/Unhinged)
22 changes: 20 additions & 2 deletions frameworks/CSharp/wiredio/benchmark_config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"framework": "wiredio",
"maintainers": ["MDA2AV"],
"tests": [
{
"default": {
Expand All @@ -17,8 +18,25 @@
"os": "Linux",
"database_os": "Linux",
"display_name": "Wired.IO",
"notes": "Only plaintext and JSON benchmarks implemented"
"notes": "Only plaintext and JSON benchmarks implemented yet"
},
"plt": {
"plaintext_url": "/plaintext",
"json_url": "/json",
"port": 8080,
"approach": "Realistic",
"classification": "Platform",
"database": "None",
"framework": "Unhinged",
"language": "C#",
"orm": "None",
"platform": ".NET",
"webserver": "Unhinged",
"os": "Linux",
"database_os": "Linux",
"display_name": "Wired.IO [Unhinged]",
"notes": "Not a framework"
}
}
]
}
}
12 changes: 12 additions & 0 deletions frameworks/CSharp/wiredio/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,15 @@ orm = "None"
platform = ".NET"
webserver = "Wired.IO"
versus = "None"

[plt]
urls.plaintext = "/plaintext"
urls.json = "/json"
approach = "Realistic"
classification = "Platform"
os = "Linux"
database_os = "Linux"
orm = "None"
platform = ".NET"
webserver = "Unhinged"
versus = "None"
26 changes: 26 additions & 0 deletions frameworks/CSharp/wiredio/src/Fullstack/Fullstack.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<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="Wired.IO" Version="9.5.0" />
</ItemGroup>

</Project>
59 changes: 59 additions & 0 deletions frameworks/CSharp/wiredio/src/Fullstack/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System.IO.Pipelines;
using System.Text.Json;
using System.Text.Json.Serialization;
using Wired.IO.App;

namespace Fullstack;

internal class Program
{
public static async Task Main(string[] args)
{
var expressBuilder = WiredApp.CreateExpressBuilder();

await expressBuilder
.Port(8080)
.MapGet("/json", scope => async ctx =>
{
var payload = new JsonMessage { Message = JsonBody };
var myHandler = CreateBoundHandler(ctx.Writer, payload);

ctx
.Respond()
.Type("application/json"u8)
.Content(myHandler, 27);

})
.MapGet("/plaintext", scope => async ctx =>
{
ctx
.Respond()
.Type("text/plain"u8)
.Content(_plainTextBody);
})
.Build()
.RunAsync();
}

private static ReadOnlySpan<byte> _plainTextBody => "Hello, World!"u8;
private const string JsonBody = "Hello, World!";

[ThreadStatic]
private static Utf8JsonWriter? t_writer;
private static readonly Action<PipeWriter, JsonMessage> StaticHandler = HandleFast;
private static Action CreateBoundHandler(PipeWriter writer, JsonMessage message) => () => StaticHandler.Invoke(writer, message);
private static void HandleFast(PipeWriter writer, JsonMessage message)
{
var utf8JsonWriter = t_writer ??= new Utf8JsonWriter(writer, new JsonWriterOptions { SkipValidation = true });
utf8JsonWriter.Reset(writer);
JsonSerializer.Serialize(utf8JsonWriter, message, SerializerContext.JsonMessage);
}

private static readonly JsonContext SerializerContext = JsonContext.Default;
}

public struct JsonMessage { public string Message { get; set; } }

[JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Serialization | JsonSourceGenerationMode.Metadata)]
[JsonSerializable(typeof(JsonMessage))]
public partial class JsonContext : JsonSerializerContext { }
25 changes: 25 additions & 0 deletions frameworks/CSharp/wiredio/src/Platform/Platform.csproj
Original file line number Diff line number Diff line change
@@ -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.1" />
</ItemGroup>
</Project>
99 changes: 99 additions & 0 deletions frameworks/CSharp/wiredio/src/Platform/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// 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)


// Number of working threads
// Reasoning behind Environment.ProcessorCount / 2
// It's the number of real cpu cores not cpu threads
// This can improve the cache hits on L1/L2 since only one thread
// is running per cpu core.
.SetNWorkersSolver(() => Environment.ProcessorCount/2)

// 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 static void RequestHandler(Connection connection)
{
// FNV-1a Hashed routes to avoid string allocations
if(connection.HashedRoute == 291830056) // /json
CommitJsonResponse(connection);

else if (connection.HashedRoute == 3454831873) // /plaintext
CommitPlainTextResponse(connection);
}

[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 changes: 22 additions & 0 deletions frameworks/CSharp/wiredio/wiredio-plt.dockerfile
Original file line number Diff line number Diff line change
@@ -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/Platform/ ./Platform/
WORKDIR /src/Platform
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"]
Loading
Loading