Skip to content

Commit be77811

Browse files
authored
Support netcoreapp3.1 in benchmark apps and call count limit (#1078)
1 parent 4827aea commit be77811

File tree

7 files changed

+125
-22
lines changed

7 files changed

+125
-22
lines changed

build/sources.props

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,12 @@
1818
$(RestoreSources);
1919
https://grpc.jfrog.io/grpc/api/nuget/v3/grpc-nuget-dev;
2020
</RestoreSources>
21+
<!-- The following is a temporary change so 5.0 build works during transition from rc to rtm -->
22+
<RestoreSources>
23+
$(RestoreSources);
24+
https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-runtime-b928f03f/nuget/v3/index.json;
25+
https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-efcore-ab94ac91/nuget/v3/index.json;
26+
</RestoreSources>
2127
</PropertyGroup>
2228
</Project>
29+

perf/benchmarkapps/GrpcAspNetCoreServer/GrpcAspNetCoreServer.csproj

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<TargetFramework Condition="'$(BenchmarksTargetFramework)' != ''">$(BenchmarksTargetFramework)</TargetFramework>
66
<OutputType>Exe</OutputType>
77
<!-- Uncomment line below to enable gRPC-Web on the server -->
8-
<!--<DefineConstants>$(DefineConstants);GRPC_WEB</DefineConstants>-->
8+
<DefineConstants Condition="'$(EnableGrpcWeb)' == 'true'">$(DefineConstants);GRPC_WEB</DefineConstants>
99

1010
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
1111
<!-- Uncomment line below to automatically compile .proto files in the project directory -->
@@ -34,12 +34,25 @@
3434
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
3535
</Content>
3636

37-
<ProjectReference Include="..\..\..\src\Grpc.AspNetCore.Server\Grpc.AspNetCore.Server.csproj" />
37+
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
38+
</ItemGroup>
39+
40+
<ItemGroup Condition="'$(EnableGrpcWeb)' == 'true'">
3841
<ProjectReference Include="..\..\..\src\Grpc.AspNetCore.Web\Grpc.AspNetCore.Web.csproj" />
42+
</ItemGroup>
43+
44+
<ItemGroup Condition="'$(TargetFramework)' == 'net5.0'">
45+
<ProjectReference Include="..\..\..\src\Grpc.AspNetCore.Server\Grpc.AspNetCore.Server.csproj" />
3946

4047
<PackageReference Include="Google.Protobuf" Version="$(GoogleProtobufPackageVersion)" />
4148
<PackageReference Include="Grpc.Tools" Version="$(GrpcPackageVersion)" PrivateAssets="All" />
42-
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
49+
4350
<PackageReference Include="Microsoft.AspNetCore.Authentication.Certificate" Version="$(MicrosoftAspNetCoreAppPackageVersion)" />
4451
</ItemGroup>
52+
53+
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
54+
<PackageReference Include="Grpc.AspNetCore.Server" Version="2.23.2" />
55+
<PackageReference Include="Google.Protobuf" Version="3.9.1" />
56+
<PackageReference Include="Grpc.Tools" Version="2.23.0" PrivateAssets="All" />
57+
</ItemGroup>
4558
</Project>

perf/benchmarkapps/GrpcAspNetCoreServer/Startup.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
using System.Security.Cryptography.X509Certificates;
2222
using System.Text;
2323
using Grpc.Testing;
24+
#if NET5_0
2425
using Microsoft.AspNetCore.Authentication.Certificate;
26+
#endif
2527
using Microsoft.AspNetCore.Builder;
2628
using Microsoft.AspNetCore.Http;
2729
using Microsoft.AspNetCore.Routing;
@@ -45,8 +47,10 @@ public void ConfigureServices(IServiceCollection services)
4547
{
4648
services.AddGrpc(o =>
4749
{
50+
#if NET5_0
4851
// Small performance benefit to not add catch-all routes to handle UNIMPLEMENTED for unknown services
4952
o.IgnoreUnknownServices = true;
53+
#endif
5054
});
5155
services.Configure<RouteOptions>(c =>
5256
{
@@ -56,6 +60,7 @@ public void ConfigureServices(IServiceCollection services)
5660
services.AddSingleton<BenchmarkServiceImpl>();
5761
services.AddControllers();
5862

63+
#if NET5_0
5964
bool.TryParse(_config["enableCertAuth"], out var enableCertAuth);
6065
if (enableCertAuth)
6166
{
@@ -68,6 +73,7 @@ public void ConfigureServices(IServiceCollection services)
6873
options.AllowedCertificateTypes = CertificateTypes.All;
6974
});
7075
}
76+
#endif
7177
}
7278

7379
public void Configure(IApplicationBuilder app, IHostApplicationLifetime applicationLifetime)
@@ -77,19 +83,23 @@ public void Configure(IApplicationBuilder app, IHostApplicationLifetime applicat
7783

7884
app.UseRouting();
7985

86+
#if NET5_0
8087
bool.TryParse(_config["enableCertAuth"], out var enableCertAuth);
8188
if (enableCertAuth)
8289
{
8390
app.UseAuthentication();
8491
app.UseAuthorization();
8592
}
93+
#endif
8694

95+
#if GRPC_WEB
8796
bool.TryParse(_config["enableGrpcWeb"], out var enableGrpcWeb);
8897

8998
if (enableGrpcWeb)
9099
{
91100
app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true });
92101
}
102+
#endif
93103

94104
app.UseMiddleware<ServiceProvidersMiddleware>();
95105

@@ -129,11 +139,13 @@ public void Configure(IApplicationBuilder app, IHostApplicationLifetime applicat
129139

130140
private void ConfigureAuthorization(IEndpointConventionBuilder builder)
131141
{
142+
#if NET5_0
132143
bool.TryParse(_config["enableCertAuth"], out var enableCertAuth);
133144
if (enableCertAuth)
134145
{
135146
builder.RequireAuthorization();
136147
}
148+
#endif
137149
}
138150
}
139151
}

perf/benchmarkapps/GrpcClient/ClientOptions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@ namespace GrpcClient
2323
public class ClientOptions
2424
{
2525
public string? Url { get; set; }
26+
#if NET5_0
2627
public string? UdsFileName { get; set; }
28+
#endif
2729
public int Connections { get; set; }
2830
public int Warmup { get; set; }
2931
public int Duration { get; set; }
32+
public int? CallCount { get; set; }
3033
public string? Scenario { get; set; }
3134
public bool Latency { get; set; }
3235
public string? Protocol { get; set; }

perf/benchmarkapps/GrpcClient/GrpcClient.csproj

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<TargetFramework>net5.0</TargetFramework>
55
<TargetFramework Condition="'$(BenchmarksTargetFramework)' != ''">$(BenchmarksTargetFramework)</TargetFramework>
66
<OutputType>Exe</OutputType>
7+
<DefineConstants Condition="'$(EnableGrpcWeb)' == 'true'">$(DefineConstants);GRPC_WEB</DefineConstants>
78
<!-- Enable server GC to more closely simulate a microservice app making calls -->
89
<ServerGarbageCollection>true</ServerGarbageCollection>
910
</PropertyGroup>
@@ -22,12 +23,6 @@
2223
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
2324
</None>
2425

25-
<ProjectReference Include="..\..\..\src\Grpc.Net.Client.Web\Grpc.Net.Client.Web.csproj" />
26-
<ProjectReference Include="..\..\..\src\Grpc.Net.Client\Grpc.Net.Client.csproj" />
27-
28-
<PackageReference Include="Google.Protobuf" Version="$(GoogleProtobufPackageVersion)" />
29-
<PackageReference Include="Grpc.Core" Version="$(GrpcPackageVersion)" />
30-
<PackageReference Include="Grpc.Tools" Version="$(GrpcPackageVersion)" PrivateAssets="All" />
3126
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsPackageVersion)" />
3227
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsPackageVersion)" />
3328
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
@@ -46,4 +41,23 @@
4641
</None>
4742
</ItemGroup>
4843

44+
<ItemGroup Condition="'$(EnableGrpcWeb)' == 'true'">
45+
<ProjectReference Include="..\..\..\src\Grpc.AspNetCore.Web\Grpc.AspNetCore.Web.csproj" />
46+
</ItemGroup>
47+
48+
<ItemGroup Condition="'$(TargetFramework)' == 'net5.0'">
49+
<ProjectReference Include="..\..\..\src\Grpc.Net.Client\Grpc.Net.Client.csproj" />
50+
51+
<PackageReference Include="Google.Protobuf" Version="$(GoogleProtobufPackageVersion)" />
52+
<PackageReference Include="Grpc.Core" Version="$(GrpcPackageVersion)" />
53+
<PackageReference Include="Grpc.Tools" Version="$(GrpcPackageVersion)" PrivateAssets="All" />
54+
</ItemGroup>
55+
56+
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
57+
<PackageReference Include="Grpc.Net.Client" Version="2.23.2" />
58+
<PackageReference Include="Google.Protobuf" Version="3.9.1" />
59+
<PackageReference Include="Grpc.Core" Version="2.23.0" />
60+
<PackageReference Include="Grpc.Tools" Version="2.23.0" PrivateAssets="All" />
61+
</ItemGroup>
62+
4963
</Project>

perf/benchmarkapps/GrpcClient/Program.cs

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class Program
4848
private static List<int> _requestsPerConnection = null!;
4949
private static List<int> _errorsPerConnection = null!;
5050
private static List<List<double>> _latencyPerConnection = null!;
51+
private static int _callsStarted;
5152
private static double _maxLatency;
5253
private static Stopwatch _workTimer = new Stopwatch();
5354
private static volatile bool _warmingUp;
@@ -59,6 +60,7 @@ class Program
5960
private static ILoggerFactory? _loggerFactory;
6061
private static SslCredentials? _credentials;
6162
private static StringBuilder _errorStringBuilder = new StringBuilder();
63+
private static CancellationTokenSource _cts = new CancellationTokenSource();
6264

6365
public static async Task<int> Main(string[] args)
6466
{
@@ -68,6 +70,7 @@ public static async Task<int> Main(string[] args)
6870
rootCommand.AddOption(new Option<int>(new string[] { "-c", "--connections" }, () => 1, "Total number of connections to keep open"));
6971
rootCommand.AddOption(new Option<int>(new string[] { "-w", "--warmup" }, () => 5, "Duration of the warmup in seconds"));
7072
rootCommand.AddOption(new Option<int>(new string[] { "-d", "--duration" }, () => 10, "Duration of the test in seconds"));
73+
rootCommand.AddOption(new Option<int>(new string[] { "--callCount" }, "Call count of test"));
7174
rootCommand.AddOption(new Option<string>(new string[] { "-s", "--scenario" }, "Scenario to run") { Required = true });
7275
rootCommand.AddOption(new Option<bool>(new string[] { "-l", "--latency" }, () => false, "Whether to collect detailed latency"));
7376
rootCommand.AddOption(new Option<string>(new string[] { "-p", "--protocol" }, "HTTP protocol") { Required = true });
@@ -112,17 +115,26 @@ public static async Task<int> Main(string[] args)
112115

113116
private static async Task StartScenario()
114117
{
115-
var cts = new CancellationTokenSource();
116-
cts.CancelAfter(TimeSpan.FromSeconds(_options.Duration + _options.Warmup));
118+
if (_options.CallCount == null)
119+
{
120+
Log("Warm up: " + _options.Warmup);
121+
Log("Duration: " + _options.Duration);
122+
123+
_cts.CancelAfter(TimeSpan.FromSeconds(_options.Duration + _options.Warmup));
117124

118-
_warmingUp = true;
119-
_ = Task.Run(async () =>
125+
_warmingUp = true;
126+
_ = Task.Run(async () =>
127+
{
128+
await Task.Delay(TimeSpan.FromSeconds(_options.Warmup));
129+
_workTimer.Restart();
130+
_warmingUp = false;
131+
Log("Finished warming up.");
132+
});
133+
}
134+
else
120135
{
121-
await Task.Delay(TimeSpan.FromSeconds(_options.Warmup));
122-
_workTimer.Restart();
123-
_warmingUp = false;
124-
Log("Finished warming up.");
125-
});
136+
Log("Call count: " + _options.CallCount);
137+
}
126138

127139
var callTasks = new List<Task>();
128140

@@ -134,13 +146,13 @@ private static async Task StartScenario()
134146
switch (_options.Scenario?.ToLower())
135147
{
136148
case "unary":
137-
callFactory = (connectionId, streamId) => UnaryCall(cts, connectionId, streamId);
149+
callFactory = (connectionId, streamId) => UnaryCall(_cts, connectionId, streamId);
138150
break;
139151
case "serverstreaming":
140-
callFactory = (connectionId, streamId) => ServerStreamingCall(cts, connectionId, streamId);
152+
callFactory = (connectionId, streamId) => ServerStreamingCall(_cts, connectionId, streamId);
141153
break;
142154
case "pingpongstreaming":
143-
callFactory = (connectionId, streamId) => PingPongStreaming(cts, connectionId, streamId);
155+
callFactory = (connectionId, streamId) => PingPongStreaming(_cts, connectionId, streamId);
144156
break;
145157
default:
146158
throw new Exception($"Scenario '{_options.Scenario}' is not a known scenario.");
@@ -220,7 +232,7 @@ private static void CalculateStatistics()
220232
Log($"Least Requests per Connection: {min}");
221233
Log($"Most Requests per Connection: {max}");
222234

223-
if (_workTimer.ElapsedMilliseconds <= 0)
235+
if (_options.CallCount == null && _workTimer.ElapsedMilliseconds <= 0)
224236
{
225237
Log("Job failed to run");
226238
return;
@@ -229,6 +241,7 @@ private static void CalculateStatistics()
229241
var rps = (double)requestDelta / _workTimer.ElapsedMilliseconds * 1000;
230242
var errors = _errorsPerConnection.Sum();
231243
Log($"RPS: {rps:N0}");
244+
Log($"Total requests: {requestDelta}");
232245
Log($"Total errors: {errors}");
233246

234247
BenchmarksEventSource.Log.Metadata("grpc/rps/max", "max", "sum", "Max RPS", "RPS: max", "n0");
@@ -389,6 +402,9 @@ private static ChannelBase CreateChannel(string target)
389402
var address = useTls ? "https://" : "http://";
390403
address += target;
391404

405+
#if NETCOREAPP3_1
406+
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
407+
#endif
392408
var httpClientHandler = new SocketsHttpHandler();
393409
httpClientHandler.UseProxy = false;
394410
httpClientHandler.AllowAutoRedirect = false;
@@ -402,18 +418,24 @@ private static ChannelBase CreateChannel(string target)
402418
clientCertificate
403419
};
404420
}
421+
#if NET5_0
405422
if (!string.IsNullOrEmpty(_options.UdsFileName))
406423
{
407424
var connectionFactory = new UnixDomainSocketConnectionFactory(new UnixDomainSocketEndPoint(ResolveUdsPath(_options.UdsFileName)));
408425
httpClientHandler.ConnectCallback = connectionFactory.ConnectAsync;
409426
}
427+
#endif
410428

411429
httpClientHandler.SslOptions.RemoteCertificateValidationCallback =
412430
(object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors) => true;
413431

414432
return GrpcChannel.ForAddress(address, new GrpcChannelOptions
415433
{
434+
#if NET5_0
416435
HttpHandler = httpClientHandler,
436+
#else
437+
HttpClient = new HttpClient(httpClientHandler),
438+
#endif
417439
LoggerFactory = _loggerFactory
418440
});
419441
}
@@ -507,6 +529,11 @@ private static async Task PingPongStreaming(CancellationTokenSource cts, int con
507529

508530
while (!cts.IsCancellationRequested)
509531
{
532+
if (StartCall())
533+
{
534+
break;
535+
}
536+
510537
try
511538
{
512539
var start = DateTime.UtcNow;
@@ -547,6 +574,11 @@ private static async Task ServerStreamingCall(CancellationTokenSource cts, int c
547574

548575
while (!cts.IsCancellationRequested)
549576
{
577+
if (StartCall())
578+
{
579+
break;
580+
}
581+
550582
try
551583
{
552584
var start = DateTime.UtcNow;
@@ -582,6 +614,11 @@ private static async Task UnaryCall(CancellationTokenSource cts, int connectionI
582614

583615
while (!cts.IsCancellationRequested)
584616
{
617+
if (StartCall())
618+
{
619+
break;
620+
}
621+
585622
try
586623
{
587624
var start = DateTime.UtcNow;
@@ -600,5 +637,18 @@ private static async Task UnaryCall(CancellationTokenSource cts, int connectionI
600637

601638
Log(connectionId, streamId, $"Finished {_options.Scenario}");
602639
}
640+
641+
private static bool StartCall()
642+
{
643+
Interlocked.Increment(ref _callsStarted);
644+
if (_options.CallCount != null && _callsStarted > _options.CallCount)
645+
{
646+
Log($"Reached {_options.CallCount}");
647+
_cts.Cancel();
648+
return true;
649+
}
650+
651+
return false;
652+
}
603653
}
604654
}

perf/benchmarkapps/GrpcClient/UnixDomainSocketConnectionFactory.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
using System.Threading;
2424
using System.Threading.Tasks;
2525

26+
#if NET5_0
27+
2628
namespace GrpcClient
2729
{
2830
public class UnixDomainSocketConnectionFactory
@@ -51,3 +53,5 @@ public async ValueTask<Stream> ConnectAsync(SocketsHttpConnectionContext _, Canc
5153
}
5254
}
5355
}
56+
57+
#endif

0 commit comments

Comments
 (0)