You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Artifacts land in a per-run timestamped folder `src/BenchmarkDotNet.Artifacts/{yyyyMMdd_HHmmss}/`
85
+
(gitignored). All three configs share one timestamp captured once at process start
86
+
(`BenchmarkArtifacts.Path`), so a run spanning multiple configs resolves to a single root — distinct
87
+
per-config paths are what triggers the `GetRootArtifactsFolderPath` crash. Charts (point at the run
88
+
folder you want):
89
+
90
+
```bash
91
+
cd docs && npm install # once, pulls chart.js for offline inlining
92
+
npm run charts -- ../src/GaudiHTTP.Benchmarks/BenchmarkDotNet.Artifacts/20260630_120000 # -> .../charts.html
93
+
```
94
+
95
+
`charts.html` is a single self-contained file (Chart.js inlined, no server): throughput, latency
96
+
percentiles, and allocation. **Allocation bars are fed only from the EventPipe total in
97
+
`*.alloc-by-type.json` — never the MemoryDiagnoser "Allocated" column.**
98
+
99
+
Four measurement constraints (non-obvious, baked into the configs — do not regress them):
100
+
1.**MemoryDiagnoser only measures the calling thread** (`GetAllocatedBytesForCurrentThread`), so its
101
+
"Allocated" column is structurally wrong for the Akka client / Task workloads (≈46 KB vs real
102
+
~3.5 MB). Measure allocation **only** process-wide via EventPipe + `AllocationByTypeExporter`.
103
+
2.**Client allocation needs the server out-of-process** (`ServerProcessHandle`, internal
104
+
`--bench-server` entry in `Program.cs`). In-process Kestrel contaminates the process-wide total
105
+
and throttles the client (shared thread pool) → ~3.7× under-count.
106
+
3.**CPU- or network-heavy benches must use `RunStrategy.Monitoring` + fixed low iteration counts +
107
+
`EventPipeProfiler(performExtraBenchmarksRun: false)`**, else the default Throughput strategy
108
+
auto-scales to thousands of invocations and pins every core for minutes.
109
+
4.**Throughput comparisons may stay in-process** (combined allocation acceptable there); the metric
110
+
is Mean / Req-per-sec, not allocation.
111
+
50
112
## Debugging with Senf.Tracing
51
113
52
114
All state machines and stage logic are permanently instrumented with `Servus.Senf.Tracing`. To debug issues, activate tracing in tests — no ad-hoc `Console.Error.WriteLine` needed.
Copy file name to clipboardExpand all lines: docs/api/feature-options.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# Feature Options and Builders
2
2
3
-
Feature options configure optional features and are applied via the builder API, not through `TurboClientOptions`. All `With*` methods accept an optional configuration delegate; calling them without arguments enables the feature with its defaults. See [Configuration guide](/client/configuration) for builder usage.
3
+
Feature options configure optional features and are applied via the builder API, not through `GaudiClientOptions`. All `With*` methods accept an optional configuration delegate; calling them without arguments enables the feature with its defaults. See [Configuration guide](/client/configuration) for builder usage.
4
4
5
5
## RetryOptions
6
6
@@ -191,7 +191,7 @@ public static class GaudiHttpClientBuilderExtensions
@@ -139,7 +139,7 @@ public sealed class TurboListenOptions(IPAddress address, ushort port)
139
139
140
140
## Transport Buffer Options
141
141
142
-
Controls backpressure thresholds on the read/write pipes between the OS socket and the HTTP pipeline. Applied per-connection for TCP and per-stream for QUIC. Set via `TurboListenOptions.Transport`. Every property is nullable — properties left at `null` fall back to the protocol-optimized default individually, so you only need to set the thresholds you want to change. A resume threshold above its pause threshold fails endpoint resolution with `InvalidOperationException`.
142
+
Controls backpressure thresholds on the read/write pipes between the OS socket and the HTTP pipeline. Applied per-connection for TCP and per-stream for QUIC. Set via `GaudiListenOptions.Transport`. Every property is nullable — properties left at `null` fall back to the protocol-optimized default individually, so you only need to set the thresholds you want to change. A resume threshold above its pause threshold fails endpoint resolution with `InvalidOperationException`.
The return value is `IGaudiHttpClientBuilder` — all further options are registered as extension methods on it. The graph is not materialized here, but on the first `CreateClient(name)` call of the factory.
56
56
57
-
HTTP version and default headers are set on the `IGaudiHttpClient` instance, not on `TurboClientOptions`:
57
+
HTTP version and default headers are set on the `IGaudiHttpClient` instance, not on `GaudiClientOptions`:
58
58
59
59
```csharp
60
60
varclient=factory.CreateClient("myapi");
@@ -88,7 +88,7 @@ These methods only register their configuration in `IServiceCollection` (as `IOp
88
88
89
89
> **Note:** Feature configuration (redirect, retry, cache, cookies) is done exclusively through the
> These are not properties on `TurboClientOptions`.
91
+
> These are not properties on `GaudiClientOptions`.
92
92
93
93
---
94
94
@@ -97,7 +97,7 @@ These methods only register their configuration in `IServiceCollection` (as `IOp
97
97
Instead of `DelegatingHandler`, GaudiHTTP provides its own stream-compatible middleware abstraction. The interface is intentionally simple — no Akka knowledge required:
98
98
99
99
```csharp
100
-
publicabstractclassTurboHandler
100
+
publicabstractclassGaudiHandler
101
101
{
102
102
// Optional: request transform — default is pass-through
103
103
publicvirtualHttpRequestMessageProcessRequest(
@@ -212,7 +212,7 @@ public class PaymentService(IGaudiHttpClientFactory factory)
0 commit comments