Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
10 changes: 10 additions & 0 deletions .github/actions/allocation-gate/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ runs:
--allocation-gate-self-test
--output "${{ inputs.artifact-directory }}/self-test.json"

- name: Server call admission benchmark smoke test
shell: bash
run: >-
dotnet run
--project test/SharpLink.Benchmarks/SharpLink.Benchmarks.csproj
-c Release
--no-build
--
--server-call-admission-smoke-test
Comment thread
SunSi12138 marked this conversation as resolved.
Resolved

- name: Enforce allocation budgets
shell: bash
env:
Expand Down
9 changes: 9 additions & 0 deletions eng/perf/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ dotnet run --project test/SharpLink.Benchmarks/SharpLink.Benchmarks.csproj \
--output artifacts/perf/allocation-gate-self-test.json
```

The server call-admission benchmark also has a fast smoke test that initializes its real TCP-backed
benchmark environment, acquires and releases one call slot, and cleans up without running the full
BenchmarkDotNet measurement suite. CI runs this after building the benchmark project:

```bash
dotnet run --project test/SharpLink.Benchmarks/SharpLink.Benchmarks.csproj \
-c Release --no-build -- --server-call-admission-smoke-test
```

A negative-control run can inject managed allocation into each measured target operation:

```bash
Expand Down
6 changes: 6 additions & 0 deletions test/SharpLink.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ public static async Task Main(string[] args)
AllocationGateRunner.RunSelfTests(args[1..]);
return;
}
if (args.Length > 0 && string.Equals(
args[0], "--server-call-admission-smoke-test", StringComparison.Ordinal))
{
await ServerCallAdmissionHotPathBenchmarks.RunSmokeTestAsync();
Comment thread
SunSi12138 marked this conversation as resolved.
Resolved
return;
}
if (args.Length > 0 && string.Equals(
args[0], "--unsafe-blit-padding-evidence", StringComparison.Ordinal))
{
Expand Down
34 changes: 22 additions & 12 deletions test/SharpLink.Benchmarks/ServerCallAdmissionHotPathBenchmarks.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.Collections.Concurrent;
using System.Linq;
using System.Reflection;
using BenchmarkDotNet.Attributes;
Expand Down Expand Up @@ -31,23 +30,34 @@ public async Task Setup()
options.FlowControl.MaxConcurrentCallsPerServer = 1_024;
});

_server = (SharpLinkServer)(typeof(BenchmarkEnvironment).GetField(
"_server",
BindingFlags.Instance | BindingFlags.NonPublic)
?.GetValue(_environment)
?? throw new InvalidOperationException("Cannot resolve benchmark server."));
var connections = (ConcurrentDictionary<string, ServerConnectionState>)(
typeof(SharpLinkServer).GetField(
"_connections",
_server = (SharpLinkServer)_environment.Server;
var registry = typeof(SharpLinkServer).GetField(
"_connectionRegistry",
BindingFlags.Instance | BindingFlags.NonPublic)
?.GetValue(_server)
?? throw new InvalidOperationException("Cannot resolve benchmark connection table."));
_connection = connections.Values.Single();
?.GetValue(_server) as ServerConnectionRegistry
?? throw new InvalidOperationException("Cannot resolve benchmark connection registry.");
_connection = registry.SnapshotActive().Single();
}

[GlobalCleanup]
public async Task Cleanup() => await _environment.DisposeAsync();

// Exercise GlobalSetup and a balanced admission without a full BenchmarkDotNet measurement run.
internal static async Task RunSmokeTestAsync()
{
var benchmark = new ServerCallAdmissionHotPathBenchmarks();
await benchmark.Setup();
try
{
if (benchmark.AcquireAndRelease() != 0)
throw new InvalidOperationException("Call-admission benchmark did not release its capacity.");
}
finally
{
await benchmark.Cleanup();
}
}

[Benchmark]
public int AcquireAndRelease()
{
Expand Down
Loading