e9e44a9ef0
The WP-4 runs measured the stream path only up to the bounded send channel; the probe deliberately substituted the socket hop with a controllable reader, which is exactly where the R2 SiteStreamEventBatcher lives — so batching had never been in any benchmark's hot path. The harness now also attaches per-site wire probes: a real Kestrel h2c listener hosting the production SiteStreamGrpcServer, dialed by the production SiteStreamGrpcClient with batching negotiated, batch sizes read from the production batch_size histogram via a MeterListener (--wire-probes-per-site, default 10; 0 restores the old shape). Full-scale run (10x500x75, 20-min window, results doc §8 + raw JSON): 899,807 events in 12,462 frames (mean 72.2 ev/frame, p50=p99=75), wire P99 43.4 ms vs the 250 ms budget — every batch pays the full 25 ms linger since a 75-event burst never hits the 100 cap — zero drops, zero faults, offered load 100.0% of nominal with fan-out doubled. CI smoke Fact now asserts the wire path carries traffic and observes frames.
49 lines
2.7 KiB
XML
49 lines
2.7 KiB
XML
<Project Sdk="Microsoft.NET.Sdk">
|
|
|
|
<!--
|
|
Target-scale load harness (deferred-work register #25 / Phase-8 WP-4, absorbing row 50).
|
|
|
|
Deliberately an Exe, not an xunit project: the full-scale protocol is a
|
|
~20-minute sustained run at 10 sites x 500 instances x 75 tags, which must NOT
|
|
execute as part of `dotnet test ZB.MOM.WW.ScadaBridge.slnx`. The PerformanceTests
|
|
project carries a tiny scaled-down smoke [Fact] that references this assembly so
|
|
the harness stays compiled and exercised by CI without the runtime cost.
|
|
|
|
Design memo: docs/plans/2026-08-15-target-scale-load-test-design.md
|
|
Results: docs/plans/2026-08-15-target-scale-load-test-results.md
|
|
-->
|
|
<PropertyGroup>
|
|
<TargetFramework>net10.0</TargetFramework>
|
|
<OutputType>Exe</OutputType>
|
|
<ImplicitUsings>enable</ImplicitUsings>
|
|
<Nullable>enable</Nullable>
|
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
|
<IsPackable>false</IsPackable>
|
|
<RootNamespace>ZB.MOM.WW.ScadaBridge.LoadHarness</RootNamespace>
|
|
<!-- Server GC: the harness holds ~5,000 actors and 375,000 attribute slots; the
|
|
workstation collector's single heap is not representative of a site node,
|
|
which runs under the ASP.NET Core host defaults (server GC on). -->
|
|
<ServerGarbageCollection>true</ServerGarbageCollection>
|
|
<ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>
|
|
</PropertyGroup>
|
|
|
|
<ItemGroup>
|
|
<!-- Wire-path probes: each site hosts the production SiteStreamGrpcServer on a
|
|
real Kestrel h2c listener so the R2 batcher + serialization + HTTP/2 flow
|
|
control sit inside the measured path (see Probes/SiteWireStreamHost.cs). -->
|
|
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
|
<PackageReference Include="Grpc.AspNetCore" />
|
|
</ItemGroup>
|
|
|
|
<ItemGroup>
|
|
<ProjectReference Include="../../src/ZB.MOM.WW.ScadaBridge.Commons/ZB.MOM.WW.ScadaBridge.Commons.csproj" />
|
|
<ProjectReference Include="../../src/ZB.MOM.WW.ScadaBridge.SiteRuntime/ZB.MOM.WW.ScadaBridge.SiteRuntime.csproj" />
|
|
<ProjectReference Include="../../src/ZB.MOM.WW.ScadaBridge.HealthMonitoring/ZB.MOM.WW.ScadaBridge.HealthMonitoring.csproj" />
|
|
<ProjectReference Include="../../src/ZB.MOM.WW.ScadaBridge.StoreAndForward/ZB.MOM.WW.ScadaBridge.StoreAndForward.csproj" />
|
|
<ProjectReference Include="../../src/ZB.MOM.WW.ScadaBridge.AuditLog/ZB.MOM.WW.ScadaBridge.AuditLog.csproj" />
|
|
<ProjectReference Include="../../src/ZB.MOM.WW.ScadaBridge.Communication/ZB.MOM.WW.ScadaBridge.Communication.csproj" />
|
|
<ProjectReference Include="../../src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/ZB.MOM.WW.ScadaBridge.DataConnectionLayer.csproj" />
|
|
</ItemGroup>
|
|
|
|
</Project>
|