diff --git a/.github/scripts/benchmark-client-run.sh b/.github/scripts/benchmark-client-run.sh index 3b2e0feaa..a4382a155 100644 --- a/.github/scripts/benchmark-client-run.sh +++ b/.github/scripts/benchmark-client-run.sh @@ -8,107 +8,131 @@ set -euo pipefail # $ echo $? function usage { - echo "usage: $(basename $0) --args [options]" - echo "Required:" - echo " --args string Arguments to pass when running the built binary (default: \"\")" - echo "Options:" - echo " --help Show this help message" + cat < [options] +Required: + --run-args string Arguments to pass when running the built binary (default: \"\") +Options: + --build-args string Arguments to pass when building the project (default: \"\") + --help Show this help message +EOF } while [ $# -gt 0 ]; do case $1 in # required - --args) _ARGS=$2; shift 2; ;; + --run-args) _RUN_ARGS=$2; shift 2; ;; # optional + --build-args) _BUILD_ARGS=$2; shift 2; ;; --help) usage; exit 1; ;; *) shift ;; esac done -function print() { +function print { + echo "$(date "+%Y-%m-%d %H:%M:%S") INFO(${FUNCNAME[1]:-unknown}): $*" +} +function title { echo "" - echo "$*" + echo "$(date "+%Y-%m-%d %H:%M:%S") INFO(${FUNCNAME[1]:-unknown}): # $*" +} +function error { + echo "$(date "+%Y-%m-%d %H:%M:%S") ERROR(${FUNCNAME[1]:-unknown}): # $*" >&2 } # parameter setup -repo="MagicOnion" -build_config="Release" -args="${_ARGS:=""}" -build_csproj="perf/BenchmarkApp/PerformanceTest.Client/PerformanceTest.Client.csproj" -env_settings="" - -binary_name=$(basename "$(dirname "$build_csproj")") -publish_dir="artifacts/$binary_name" -clone_path="$HOME/github/$repo" -output_dir="$clone_path/$publish_dir" -full_process_path="$output_dir/$binary_name" - -# show machine name -print "MACHINE_NAME: $(hostname)" +title "Arguments:" +print "--run-args=${_RUN_ARGS:=""}" +print "--build-args=${_BUILD_ARGS:=""}" + +title "Constants:" +print " * repo=${repo:="MagicOnion"}" +print " * build_config=${build_config:="Release"}" +print " * build_csproj=${build_csproj:="perf/BenchmarkApp/PerformanceTest.Client/PerformanceTest.Client.csproj"}" +print " * env_settings=${env_settings:=""}" +print " * binary_name=${binary_name:=$(basename "$(dirname "$build_csproj")")}" +print " * publish_dir=${publish_dir:="artifacts/$binary_name"}" +print " * clone_path=${clone_path:="$HOME/github/$repo"}" +print " * output_dir=${output_dir:="$clone_path/$publish_dir"}" +print " * full_process_path=${full_process_path:="$output_dir/$binary_name"}" + +# machine name +title "Show this machine name" +print " * MACHINE_NAME=$(hostname)" # is dotnet installed? -print "# Show installed dotnet sdk versions" -echo "dotnet sdk versions (list): $(dotnet --list-sdks)" -echo "dotnet sdk version (default): $(dotnet --version)" - -# is already clones? -print "# Check if already cloned $repo" -if [[ ! -d "$clone_path" ]]; then - echop "Failed to find $clone_path, not yet git cloned?" - exit 1 -fi - -# get branch name and set to environment variables -print "# Set branch name as Environment variable" -pushd "$clone_path" - print " ## get current git branch name" - git_branch=$(git rev-parse --abbrev-ref HEAD) - if [ -z "$git_branch" ]; then - echo "Failed to get branch name, exiting..." +title "Show installed dotnet sdk versions" +print " * dotnet sdk versions (list): $(dotnet --list-sdks)" +print " * dotnet sdk version (default): $(dotnet --version)" + +echo "::group::Is already cloned?" + title "Check if already cloned $repo" + if [[ ! -d "$clone_path" ]]; then + error "Failed to find $clone_path, not yet git cloned?" exit 1 fi - - print " ## set branch name to environment variables $git_branch" - export BRANCH_NAME="$git_branch" -popd - -# setup env -print "# Setup environment" -IFS=';' read -ra env_array <<< "$env_settings" -for item in "${env_array[@]}"; do - if [[ -n "$item" ]]; then - export "${item?}" - fi -done - -# dotnet publish -print "# dotnet publish $build_csproj" -pushd "$clone_path" - print " ## list current files under $(pwd)" - ls -l - - print " ## dotnet publish $build_csproj" - dotnet publish -c "$build_config" -p:PublishSingleFile=true --runtime linux-x64 --self-contained false "$build_csproj" -o "$publish_dir" - - print " ## list published files under $publish_dir" - ls "$publish_dir" - - print " ## add +x permission to published file $full_process_path" - chmod +x "$full_process_path" -popd - -# process check -print "# Checking process $binary_name already runnning, kill if exists" -ps -eo pid,cmd | while read -r pid cmd; do - if echo "$cmd" | grep -E "^./$binary_name" >/dev/null 2>&1; then - echo "Found & killing process $pid ($cmd)" - kill "$pid" - fi -done +echo "::endgroup::" + +echo "::group::Get branch name and set to environment variables" + title "Set branch name as Environment variable" + pushd "$clone_path" > /dev/null + print "Get current git branch name" + git_branch=$(git rev-parse --abbrev-ref HEAD) + if [ -z "$git_branch" ]; then + error "Failed to get branch name, exiting..." + exit 1 + fi + + print "Set branch name to environment variables $git_branch" + export BRANCH_NAME="$git_branch" + popd > /dev/null +echo "::endgroup::" + +echo "::group::Setup environment variables" + title "Setup environment" + IFS=';' read -ra env_array <<< "$env_settings" + for item in "${env_array[@]}"; do + if [[ -n "$item" ]]; then + export "${item?}" + fi + done +echo "::endgroup::" + +echo "::group::Kill existing process" + title "Checking process $binary_name already runnning, kill if exists" + ps -eo pid,cmd | while read -r pid cmd; do + if echo "$cmd" | grep -E "^./$binary_name" >/dev/null 2>&1; then + print "Found & killing process $pid ($cmd)" + kill "$pid" + fi + done +echo "::endgroup::" + +echo "::group::dotnet publish" + title "dotnet publish $build_csproj" + pushd "$clone_path" > /dev/null + print "List current files under $(pwd)" + ls -l + + print "Remove all files under $publish_dir" + if [[ -d "./$publish_dir" ]]; then + rm -rf "./$publish_dir" + fi + + print "dotnet publish $build_csproj $_BUILD_ARGS" + dotnet publish -c "$build_config" -p:PublishSingleFile=true --runtime linux-x64 --self-contained false "$build_csproj" -o "$publish_dir" $_BUILD_ARGS + + print "List published files under $publish_dir" + ls "$publish_dir" + + print "Add +x permission to published file $full_process_path" + chmod +x "$full_process_path" + popd > /dev/null +echo "::endgroup::" # run dotnet app -print "# Run $full_process_path $args" -pushd "$output_dir" +title "Run $full_process_path $_RUN_ARGS" +pushd "$output_dir" > /dev/null # run foreground - "./$binary_name" $args -popd + "./$binary_name" $_RUN_ARGS +popd > /dev/null diff --git a/.github/scripts/benchmark-server-run.sh b/.github/scripts/benchmark-server-run.sh index 037b2536e..1957540bd 100644 --- a/.github/scripts/benchmark-server-run.sh +++ b/.github/scripts/benchmark-server-run.sh @@ -8,114 +8,136 @@ set -euo pipefail # $ echo $? function usage { - echo "usage: $(basename $0) [options]" - echo "Required:" - echo " --args string Arguments to pass when running the built binary (default: \"\")" - echo "Options:" - echo " --help Show this help message" + cat < [options] +Required: + --run-args string Arguments to pass when running the built binary (default: \"\") +Options: + --build-args string Arguments to pass when building the project (default: \"\") + --help Show this help message +EOF } while [ $# -gt 0 ]; do case $1 in # required - --args) _ARGS=$2; shift 2; ;; + --run-args) _RUN_ARGS=$2; shift 2; ;; # optional + --build-args) _BUILD_ARGS=$2; shift 2; ;; --help) usage; exit 1; ;; *) shift ;; esac done -function print() { +function print { + echo "$(date "+%Y-%m-%d %H:%M:%S") INFO(${FUNCNAME[1]:-unknown}): $*" +} +function title { echo "" - echo "$*" + echo "$(date "+%Y-%m-%d %H:%M:%S") INFO(${FUNCNAME[1]:-unknown}): # $*" +} +function error { + echo "$(date "+%Y-%m-%d %H:%M:%S") ERROR(${FUNCNAME[1]:-unknown}): # $*" >&2 } - # parameter setup -repo="MagicOnion" -build_config="Release" -args="${_ARGS:=""}" -build_csproj="perf/BenchmarkApp/PerformanceTest.Server/PerformanceTest.Server.csproj" -env_settings="" - -binary_name=$(basename "$(dirname "$build_csproj")") -publish_dir="artifacts/$binary_name" -clone_path="$HOME/github/$repo" -output_dir="$clone_path/$publish_dir" -full_process_path="$output_dir/$binary_name" - -stdoutfile="stdout.log" -stderrfile="stderr.log" - -# show machine name -print "MACHINE_NAME: $(hostname)" +title "Arguments:" +print "--run-args=${_RUN_ARGS:=""}" +print "--build-args=${_BUILD_ARGS:=""}" + +title "Constants:" +print " * repo=${repo:="MagicOnion"}" +print " * build_config=${build_config:="Release"}" +print " * build_csproj=${build_csproj:="perf/BenchmarkApp/PerformanceTest.Server/PerformanceTest.Server.csproj"}" +print " * env_settings=${env_settings:=""}" +print " * binary_name=${binary_name:=$(basename "$(dirname "$build_csproj")")}" +print " * publish_dir=${publish_dir:="artifacts/$binary_name"}" +print " * clone_path=${clone_path:="$HOME/github/$repo"}" +print " * output_dir=${output_dir:="$clone_path/$publish_dir"}" +print " * full_process_path=${full_process_path:="$output_dir/$binary_name"}" +print " * stdoutfile=${stdoutfile:="stdout.log"}" +print " * stderrfile=${stderrfile:="stderr.log"}" + +# machine name +title "Show this machine name" +print " * MACHINE_NAME=$(hostname)" # is dotnet installed? -print "# Show installed dotnet sdk versions" -echo "dotnet sdk versions (list): $(dotnet --list-sdks)" -echo "dotnet sdk version (default): $(dotnet --version)" - -# is already clones? -print "# Check if already cloned $repo" -if [[ ! -d "$clone_path" ]]; then - echop "Failed to find $clone_path, not yet git cloned?" - exit 1 -fi - -# get branch name and set to environment variables -print "# Set branch name as Environment variable" -pushd "$clone_path" - print " ## get current git branch name" - git_branch=$(git rev-parse --abbrev-ref HEAD) - if [ -z "$git_branch" ]; then - echo "Failed to get branch name, exiting..." +title "Show installed dotnet sdk versions" +print " * dotnet sdk versions (list): $(dotnet --list-sdks)" +print " * dotnet sdk version (default): $(dotnet --version)" + +echo "::group::Is already cloned?" + title "Check if already cloned $repo" + if [[ ! -d "$clone_path" ]]; then + error "Failed to find $clone_path, not yet git cloned?" exit 1 fi - - print " ## set branch name to environment variables $git_branch" - export BRANCH_NAME="$git_branch" -popd - -# setup env -print "# Setup environment" -IFS=';' read -ra env_array <<< "$env_settings" -for item in "${env_array[@]}"; do - if [ -n "$item" ]; then - export "$item" - fi -done - -# process check -print "# Checking process $binary_name already runnning, kill if exists" -ps -eo pid,cmd | while read -r pid cmd; do - if echo "$cmd" | grep -E "^./$binary_name" >/dev/null 2>&1; then - echo "Found & killing process $pid ($cmd)" - kill "$pid" - fi -done - -# dotnet publish -print "# dotnet publish $build_csproj" -pushd "$clone_path" - print " ## list current files under $(pwd)" - ls -l - - print " ## dotnet publish $build_csproj" - dotnet publish -c "$build_config" -p:PublishSingleFile=true --runtime linux-x64 --self-contained false "$build_csproj" -o "$publish_dir" - - print " ## list published files under $publish_dir" - ls "$publish_dir" - - print " ## add +x permission to published file $full_process_path" - chmod +x "$full_process_path" -popd +echo "::endgroup::" + +echo "::group::Get branch name and set to environment variables" + title "Set branch name as Environment variable" + pushd "$clone_path" > /dev/null + print "Get current git branch name" + git_branch=$(git rev-parse --abbrev-ref HEAD) + if [ -z "$git_branch" ]; then + error "Failed to get branch name, exiting..." + exit 1 + fi + + print "Set branch name to environment variables $git_branch" + export BRANCH_NAME="$git_branch" + popd > /dev/null +echo "::endgroup::" + +echo "::group::Setup environment variables" + title "Setup environment" + IFS=';' read -ra env_array <<< "$env_settings" + for item in "${env_array[@]}"; do + if [ -n "$item" ]; then + export "$item" + fi + done +echo "::endgroup::" + +echo "::group::Kill existing process" + title "Checking process $binary_name already runnning, kill if exists" + ps -eo pid,cmd | while read -r pid cmd; do + if echo "$cmd" | grep -E "^./$binary_name" >/dev/null 2>&1; then + print "Found & killing process $pid ($cmd)" + kill "$pid" + fi + done +echo "::endgroup::" + +echo "::group::dotnet publish" + title "dotnet publish $build_csproj" + pushd "$clone_path" > /dev/null + print "List current files under $(pwd)" + ls -l + + print "Remove all files under $publish_dir" + if [[ -d "./$publish_dir" ]]; then + rm -rf "./$publish_dir" + fi + + print "dotnet publish $build_csproj $_BUILD_ARGS" + dotnet publish -c "$build_config" -p:PublishSingleFile=true --runtime linux-x64 --self-contained false "$build_csproj" -o "$publish_dir" $_BUILD_ARGS + + print "List published files under $publish_dir" + ls "$publish_dir" + + print "Add +x permission to published file $full_process_path" + chmod +x "$full_process_path" + popd > /dev/null +echo "::endgroup::" # run dotnet app -print "# Run $full_process_path $args" -pushd "$output_dir" +title "Run $full_process_path $_RUN_ARGS" +pushd "$output_dir" > /dev/null touch "${stdoutfile}" # use nohup to run background https://stackoverflow.com/questions/29142/getting-ssh-to-execute-a-command-in-the-background-on-target-machine # shellcheck disable=SC2086 - nohup "./$binary_name" $args > "${stdoutfile}" 2> "${stderrfile}" < /dev/null & + nohup "./$binary_name" $_RUN_ARGS > "${stdoutfile}" 2> "${stderrfile}" < /dev/null & # wait 10s will be enough to start the server or not sleep 10s @@ -125,8 +147,8 @@ pushd "$output_dir" # output stderr if [[ "$(stat -c%s "$stderrfile")" -ne "0" ]]; then - echo "Error found when running the server." + error "Error found when running the server." cat "${stderrfile}" exit 1 fi -popd +popd > /dev/null diff --git a/.github/scripts/benchmark-server-stop.sh b/.github/scripts/benchmark-server-stop.sh index 53711f61d..720c605d6 100644 --- a/.github/scripts/benchmark-server-stop.sh +++ b/.github/scripts/benchmark-server-stop.sh @@ -8,9 +8,11 @@ set -euo pipefail # $ echo $? function usage { - echo "usage: $(basename $0) [options]" - echo "Options:" - echo " --help Show this help message" + cat </dev/null 2>&1; then - echo "Found & killing process $pid ($cmd)" + print "Found & killing process $pid ($cmd)" kill "$pid" fi done diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index b7357ad63..36e498bfc 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -24,6 +24,12 @@ on: - workflow_dispatch_messagepack_h2 - workflow_dispatch_messagepack_h2c - workflow_dispatch_messagepack_h3 + - workflow_dispatch_messagepack_h2_nugetclient + - workflow_dispatch_messagepack_h2_nugetserver + - workflow_dispatch_messagepack_h2c_nugetclient + - workflow_dispatch_messagepack_h2c_nugetserver + - workflow_dispatch_messagepack_h3_nugetclient + - workflow_dispatch_messagepack_h3_nugetserver - issue - schedule diff --git a/Directory.Packages.props b/Directory.Packages.props index 1a7a0d6cc..e85a74d4b 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -10,6 +10,9 @@ 4.3.1 3.9.0 0.1.12 + + 4.2.2 + 1.4.3 @@ -51,8 +54,8 @@ - - + + diff --git a/perf/BenchmarkApp/PerformanceTest.Client/PerformanceTest.Client.csproj b/perf/BenchmarkApp/PerformanceTest.Client/PerformanceTest.Client.csproj index f0d1c66fb..25f6a0ba3 100644 --- a/perf/BenchmarkApp/PerformanceTest.Client/PerformanceTest.Client.csproj +++ b/perf/BenchmarkApp/PerformanceTest.Client/PerformanceTest.Client.csproj @@ -8,16 +8,27 @@ CLIENT;$(DefineConstants) - - - - + + false + + + + + + + + + + + + <_Parameter1>$(UseNuGetClient) + @@ -27,8 +38,4 @@ - - - - diff --git a/perf/BenchmarkApp/PerformanceTest.Client/Program.cs b/perf/BenchmarkApp/PerformanceTest.Client/Program.cs index 9b40b7115..996cc6ef8 100644 --- a/perf/BenchmarkApp/PerformanceTest.Client/Program.cs +++ b/perf/BenchmarkApp/PerformanceTest.Client/Program.cs @@ -68,14 +68,17 @@ async Task Main( using var channelControl = config.CreateChannel(); var controlServiceClient = MagicOnionClient.Create(channelControl); await controlServiceClient.SetMemoryProfilerCollectAllocationsAsync(true); + (DatadogMetricsRecorder.MagicOnionVersions, DatadogMetricsRecorder.EnableLatestTag) = await controlServiceClient.ExchangeMagicOnionVersionTagAsync(ApplicationInformation.Current.TagMagicOnionVersion, ApplicationInformation.Current.IsLatestMagicOnion); // keep in Client ServerInformation serverInfo; WriteLog("Gathering the server information..."); { serverInfo = await controlServiceClient.GetServerInformationAsync(); + WriteLog($"Benchmarker {serverInfo.BenchmarkerVersion}"); WriteLog($"MagicOnion {serverInfo.MagicOnionVersion}"); WriteLog($"grpc-dotnet {serverInfo.GrpcNetVersion}"); WriteLog($"{nameof(ApplicationInformation.OSDescription)}: {serverInfo.OSDescription}"); + WriteLog($"IsLatestMagicOnion {serverInfo.IsLatestMagicOnion}"); } var resultsByScenario = new Dictionary>(); @@ -112,6 +115,7 @@ async Task Main( PrintStartupInformation(writer); writer.WriteLine($"========================================"); writer.WriteLine($"Server Information:"); + writer.WriteLine($"Benchmarker {serverInfo.BenchmarkerVersion}"); writer.WriteLine($"MagicOnion {serverInfo.MagicOnionVersion}"); writer.WriteLine($"grpc-dotnet {serverInfo.GrpcNetVersion}"); writer.WriteLine($"MessagePack {serverInfo.MessagePackVersion}"); @@ -273,10 +277,12 @@ void PrintStartupInformation(TextWriter? writer = null) { writer ??= Console.Out; + writer.WriteLine($"Benchmarker {ApplicationInformation.Current.BenchmarkerVersion}"); writer.WriteLine($"MagicOnion {ApplicationInformation.Current.MagicOnionVersion}"); writer.WriteLine($"grpc-dotnet {ApplicationInformation.Current.GrpcNetVersion}"); writer.WriteLine($"MessagePack {ApplicationInformation.Current.MessagePackVersion}"); writer.WriteLine($"MemoryPack {ApplicationInformation.Current.MemoryPackVersion}"); + writer.WriteLine($"IsLatestMagicOnion {ApplicationInformation.Current.IsLatestMagicOnion}"); writer.WriteLine(); writer.WriteLine("Configurations:"); @@ -319,31 +325,42 @@ static class DatadogMetricsRecorderExtensions /// public static async Task PutClientBenchmarkMetricsAsync(this DatadogMetricsRecorder recorder, ScenarioType scenario, ApplicationInformation applicationInfo, IReadOnlyList results) { - var tags = MetricsTagCache.Get((recorder.TagBranch, recorder.TagLegend, recorder.TagStreams, recorder.TagProtocol, recorder.TagSerialization, scenario, applicationInfo), static x => [ - $"legend:{x.scenario.ToString().ToLower()}-{x.TagLegend}{x.TagStreams}", - $"branch:{x.TagBranch}", - $"streams:{x.TagStreams}", - $"protocol:{x.TagProtocol}", - $"process_arch:{x.applicationInfo.ProcessArchitecture}", - $"process_count:{x.applicationInfo.ProcessorCount}", - $"scenario:{x.scenario}", - $"serialization:{x.TagSerialization}", - ]); - var filtered = RemoveOutlinerByIQR(results); - // Don't want to await each put. Let's send it to queue and await when benchmark ends. - recorder.Record(recorder.SendAsync("benchmark.magiconion.client.rps", filtered.Select(x => x.RequestsPerSecond).Average(), DatadogMetricsType.Rate, tags, "request")); - recorder.Record(recorder.SendAsync("benchmark.magiconion.client.total_requests", filtered.Select(x => x.TotalRequests).Average(), DatadogMetricsType.Gauge, tags, "request")); - recorder.Record(recorder.SendAsync("benchmark.magiconion.client.latency_mean", filtered.Select(x => x.Latency.Mean).Average(), DatadogMetricsType.Gauge, tags, "millisecond")); - recorder.Record(recorder.SendAsync("benchmark.magiconion.client.cpu_usage_max", filtered.Select(x => x.hardware.MaxCpuUsagePercent).Average(), DatadogMetricsType.Gauge, tags, "percent")); - recorder.Record(recorder.SendAsync("benchmark.magiconion.client.cpu_usage_avg", filtered.Select(x => x.hardware.AvgCpuUsagePercent).Average(), DatadogMetricsType.Gauge, tags, "percent")); - recorder.Record(recorder.SendAsync("benchmark.magiconion.client.memory_usage_max", filtered.Select(x => x.hardware.MaxMemoryUsageMB).Average(), DatadogMetricsType.Gauge, tags, "megabyte")); - recorder.Record(recorder.SendAsync("benchmark.magiconion.client.memory_usage_avg", filtered.Select(x => x.hardware.AvgMemoryUsageMB).Average(), DatadogMetricsType.Gauge, tags, "megabyte")); + Post(recorder, scenario, applicationInfo, filtered, false); + if (DatadogMetricsRecorder.EnableLatestTag) + { + Post(recorder, scenario, applicationInfo, filtered, true); + } // wait until send complete await recorder.WaitSaveAsync(); + static void Post(DatadogMetricsRecorder recorder, ScenarioType scenario, ApplicationInformation applicationInfo, IReadOnlyList filtered, bool enableLatestTag) + { + var magicOnionTag = enableLatestTag ? recorder.TagLatestMagicOnion : recorder.TagMagicOnion; + var tags = MetricsTagCache.Get((recorder.TagBranch, recorder.TagLegend, recorder.TagStreams, recorder.TagProtocol, recorder.TagSerialization, magicOnionTag, scenario, applicationInfo), static x => [ + $"legend:{x.scenario.ToString().ToLower()}-{x.TagLegend}{x.TagStreams}", + $"branch:{x.TagBranch}", + $"magiconion:{x.magicOnionTag}", + $"protocol:{x.TagProtocol}", + $"process_arch:{x.applicationInfo.ProcessArchitecture}", + $"process_count:{x.applicationInfo.ProcessorCount}", + $"scenario:{x.scenario}", + $"serialization:{x.TagSerialization}", + $"streams:{x.TagStreams}", + ]); + + // Don't want to await each put. Let's send it to queue and await when benchmark ends. + recorder.Record(recorder.SendAsync("benchmark.magiconion.client.rps", filtered.Select(x => x.RequestsPerSecond).Average(), DatadogMetricsType.Rate, tags, "request")); + recorder.Record(recorder.SendAsync("benchmark.magiconion.client.total_requests", filtered.Select(x => x.TotalRequests).Average(), DatadogMetricsType.Gauge, tags, "request")); + recorder.Record(recorder.SendAsync("benchmark.magiconion.client.latency_mean", filtered.Select(x => x.Latency.Mean).Average(), DatadogMetricsType.Gauge, tags, "millisecond")); + recorder.Record(recorder.SendAsync("benchmark.magiconion.client.cpu_usage_max", filtered.Select(x => x.hardware.MaxCpuUsagePercent).Average(), DatadogMetricsType.Gauge, tags, "percent")); + recorder.Record(recorder.SendAsync("benchmark.magiconion.client.cpu_usage_avg", filtered.Select(x => x.hardware.AvgCpuUsagePercent).Average(), DatadogMetricsType.Gauge, tags, "percent")); + recorder.Record(recorder.SendAsync("benchmark.magiconion.client.memory_usage_max", filtered.Select(x => x.hardware.MaxMemoryUsageMB).Average(), DatadogMetricsType.Gauge, tags, "megabyte")); + recorder.Record(recorder.SendAsync("benchmark.magiconion.client.memory_usage_avg", filtered.Select(x => x.hardware.AvgMemoryUsageMB).Average(), DatadogMetricsType.Gauge, tags, "megabyte")); + } + // Remove Outliner by IQR static IReadOnlyList RemoveOutlinerByIQR(IReadOnlyList data) { diff --git a/perf/BenchmarkApp/PerformanceTest.Server/PerfTestControlService.cs b/perf/BenchmarkApp/PerformanceTest.Server/PerfTestControlService.cs index d89d6e2a4..069b531f3 100644 --- a/perf/BenchmarkApp/PerformanceTest.Server/PerfTestControlService.cs +++ b/perf/BenchmarkApp/PerformanceTest.Server/PerfTestControlService.cs @@ -2,6 +2,7 @@ using MagicOnion; using MagicOnion.Server; using PerformanceTest.Shared; +using PerformanceTest.Shared.Reporting; namespace PerformanceTest.Server; @@ -11,6 +12,8 @@ public UnaryResult GetServerInformationAsync() { return UnaryResult.FromResult(new ServerInformation( Environment.MachineName, + ApplicationInformation.Current.BenchmarkerVersion, + ApplicationInformation.Current.IsLatestMagicOnion, ApplicationInformation.Current.MagicOnionVersion, ApplicationInformation.Current.GrpcNetVersion, ApplicationInformation.Current.MessagePackVersion, @@ -26,6 +29,18 @@ public UnaryResult GetServerInformationAsync() ApplicationInformation.Current.IsAttached)); } + public UnaryResult<(string serverMagicOnionVersion, bool enableLatestTag)> ExchangeMagicOnionVersionTagAsync(string? clientMagicOnionVersion, bool isLatestMagicOnionVersion) + { + var versionTag = $"{clientMagicOnionVersion}x{ApplicationInformation.Current.TagMagicOnionVersion}"; + // Both Server and Client is latest + var isLatestTagEnabled = ApplicationInformation.Current.IsLatestMagicOnion && isLatestMagicOnionVersion; + + // keep in server + DatadogMetricsRecorder.MagicOnionVersions = versionTag; + DatadogMetricsRecorder.EnableLatestTag = isLatestTagEnabled; + return UnaryResult.FromResult((versionTag, isLatestTagEnabled)); + } + public UnaryResult SetMemoryProfilerCollectAllocationsAsync(bool enable) { MemoryProfiler.CollectAllocations(enable); diff --git a/perf/BenchmarkApp/PerformanceTest.Server/PerfTestService.cs b/perf/BenchmarkApp/PerformanceTest.Server/PerfTestService.cs index 57f3c821c..4617de1f4 100644 --- a/perf/BenchmarkApp/PerformanceTest.Server/PerfTestService.cs +++ b/perf/BenchmarkApp/PerformanceTest.Server/PerfTestService.cs @@ -11,6 +11,8 @@ public UnaryResult GetServerInformationAsync() { return UnaryResult.FromResult(new ServerInformation( Environment.MachineName, + ApplicationInformation.Current.BenchmarkerVersion, + ApplicationInformation.Current.IsLatestMagicOnion, ApplicationInformation.Current.MagicOnionVersion, ApplicationInformation.Current.GrpcNetVersion, ApplicationInformation.Current.MessagePackVersion, diff --git a/perf/BenchmarkApp/PerformanceTest.Server/PerformanceTest.Server.csproj b/perf/BenchmarkApp/PerformanceTest.Server/PerformanceTest.Server.csproj index 95007b974..31505570a 100644 --- a/perf/BenchmarkApp/PerformanceTest.Server/PerformanceTest.Server.csproj +++ b/perf/BenchmarkApp/PerformanceTest.Server/PerformanceTest.Server.csproj @@ -7,10 +7,31 @@ SERVER;$(DefineConstants) - + + false + + + + + + + + + + + + + + + + + + <_Parameter1>$(UseNuGetServer) + + @@ -19,9 +40,4 @@ - - - - - diff --git a/perf/BenchmarkApp/PerformanceTest.Server/ProfileService.cs b/perf/BenchmarkApp/PerformanceTest.Server/ProfileService.cs index dbea8a75b..db8feab6e 100644 --- a/perf/BenchmarkApp/PerformanceTest.Server/ProfileService.cs +++ b/perf/BenchmarkApp/PerformanceTest.Server/ProfileService.cs @@ -41,23 +41,37 @@ static class DatadogMetricsRecorderExtensions /// public static async Task PutServerBenchmarkMetricsAsync(this DatadogMetricsRecorder recorder, ApplicationInformation applicationInfo, HardwarePerformanceResult result) { - var tags = MetricsTagCache.Get((recorder.TagBranch, recorder.TagLegend, recorder.TagStreams, recorder.TagProtocol, recorder.TagSerialization, applicationInfo), static x => [ - $"legend:{x.TagLegend}{x.TagStreams}", - $"branch:{x.TagBranch}", - $"streams:{x.TagStreams}", - $"protocol:{x.TagProtocol}", - $"process_arch:{x.applicationInfo.ProcessArchitecture}", - $"process_count:{x.applicationInfo.ProcessorCount}", - $"serialization:{x.TagSerialization}", - ]); - - // Don't want to await each put. Let's send it to queue and await when benchmark ends. - recorder.Record(recorder.SendAsync("benchmark.magiconion.server.cpu_usage_max", result.MaxCpuUsagePercent, DatadogMetricsType.Gauge, tags, "percent")); - recorder.Record(recorder.SendAsync("benchmark.magiconion.server.cpu_usage_avg", result.AvgCpuUsagePercent, DatadogMetricsType.Gauge, tags, "percent")); - recorder.Record(recorder.SendAsync("benchmark.magiconion.server.memory_usage_max", result.MaxMemoryUsageMB, DatadogMetricsType.Gauge, tags, "megabyte")); - recorder.Record(recorder.SendAsync("benchmark.magiconion.server.memory_usage_avg", result.AvgMemoryUsageMB, DatadogMetricsType.Gauge, tags, "megabyte")); + if (string.IsNullOrEmpty(recorder.TagMagicOnion)) + return; + + Post(recorder, applicationInfo, result, false); + if (DatadogMetricsRecorder.EnableLatestTag) + { + Post(recorder, applicationInfo, result, true); + } // wait until send complete await recorder.WaitSaveAsync(); + + static void Post(DatadogMetricsRecorder recorder, ApplicationInformation applicationInfo, HardwarePerformanceResult result, bool isMagicOnionLatest) + { + var magicOnionTag = isMagicOnionLatest ? recorder.TagLatestMagicOnion : recorder.TagMagicOnion; + var tags = MetricsTagCache.Get((recorder.TagBranch, recorder.TagLegend, recorder.TagStreams, recorder.TagProtocol, recorder.TagSerialization, magicOnionTag, applicationInfo), static x => [ + $"legend:{x.TagLegend}{x.TagStreams}", + $"branch:{x.TagBranch}", + $"magiconion:{x.magicOnionTag}", + $"protocol:{x.TagProtocol}", + $"process_arch:{x.applicationInfo.ProcessArchitecture}", + $"process_count:{x.applicationInfo.ProcessorCount}", + $"serialization:{x.TagSerialization}", + $"streams:{x.TagStreams}", + ]); + + // Don't want to await each put. Let's send it to queue and await when benchmark ends. + recorder.Record(recorder.SendAsync("benchmark.magiconion.server.cpu_usage_max", result.MaxCpuUsagePercent, DatadogMetricsType.Gauge, tags, "percent")); + recorder.Record(recorder.SendAsync("benchmark.magiconion.server.cpu_usage_avg", result.AvgCpuUsagePercent, DatadogMetricsType.Gauge, tags, "percent")); + recorder.Record(recorder.SendAsync("benchmark.magiconion.server.memory_usage_max", result.MaxMemoryUsageMB, DatadogMetricsType.Gauge, tags, "megabyte")); + recorder.Record(recorder.SendAsync("benchmark.magiconion.server.memory_usage_avg", result.AvgMemoryUsageMB, DatadogMetricsType.Gauge, tags, "megabyte")); + } } } diff --git a/perf/BenchmarkApp/PerformanceTest.Server/StartupService.cs b/perf/BenchmarkApp/PerformanceTest.Server/StartupService.cs index 705380f28..4a011750f 100644 --- a/perf/BenchmarkApp/PerformanceTest.Server/StartupService.cs +++ b/perf/BenchmarkApp/PerformanceTest.Server/StartupService.cs @@ -20,10 +20,12 @@ public StartupService(IHostApplicationLifetime applicationLifetime, IServer serv private void PrintStartupInformation() { + Console.WriteLine($"Benchmarker {ApplicationInformation.Current.BenchmarkerVersion}"); Console.WriteLine($"MagicOnion {ApplicationInformation.Current.MagicOnionVersion}"); Console.WriteLine($"grpc-dotnet {ApplicationInformation.Current.GrpcNetVersion}"); Console.WriteLine($"MessagePack {ApplicationInformation.Current.MessagePackVersion}"); Console.WriteLine($"MemoryPack {ApplicationInformation.Current.MemoryPackVersion}"); + Console.WriteLine($"IsLatestMagicOnion {ApplicationInformation.Current.IsLatestMagicOnion}"); Console.WriteLine(); Console.WriteLine($"Listening on:"); diff --git a/perf/BenchmarkApp/PerformanceTest.Shared/ApplicationInformation.cs b/perf/BenchmarkApp/PerformanceTest.Shared/ApplicationInformation.cs index 103ffdfb6..d85640784 100644 --- a/perf/BenchmarkApp/PerformanceTest.Shared/ApplicationInformation.cs +++ b/perf/BenchmarkApp/PerformanceTest.Shared/ApplicationInformation.cs @@ -9,13 +9,20 @@ public class ApplicationInformation { public static ApplicationInformation Current { get; } = new ApplicationInformation(); + public bool IsLatestMagicOnion { get; } = typeof(ApplicationInformation).Assembly.GetCustomAttribute()?.IsLatest ?? true; // set from csproj + + public string? BenchmarkerVersion { get; } = typeof(ApplicationInformation).Assembly.GetCustomAttribute()?.InformationalVersion; + #if SERVER + public string? TagMagicOnionVersion { get; } = RemoveHashFromVersion(typeof(MagicOnion.Server.MagicOnionEngine).Assembly.GetCustomAttribute()?.InformationalVersion); public string? MagicOnionVersion { get; } = typeof(MagicOnion.Server.MagicOnionEngine).Assembly.GetCustomAttribute()?.InformationalVersion; public string? GrpcNetVersion { get; } = typeof(Grpc.AspNetCore.Server.GrpcServiceOptions).Assembly.GetCustomAttribute()?.InformationalVersion; #elif CLIENT + public string? TagMagicOnionVersion { get; } = RemoveHashFromVersion(typeof(MagicOnion.Client.MagicOnionClient).Assembly.GetCustomAttribute()?.InformationalVersion); public string? MagicOnionVersion { get; } = typeof(MagicOnion.Client.MagicOnionClient).Assembly.GetCustomAttribute()?.InformationalVersion; public string? GrpcNetVersion { get; } = typeof(Grpc.Net.Client.GrpcChannel).Assembly.GetCustomAttribute()?.InformationalVersion; #else + public string? TagMagicOnionVersion { get; } = RemoveHashFromVersion(typeof(MagicOnion.UnaryResult).Assembly.GetCustomAttribute()?.InformationalVersion); public string? MagicOnionVersion { get; } = typeof(MagicOnion.UnaryResult).Assembly.GetCustomAttribute()?.InformationalVersion; public string? GrpcNetVersion { get; } = default; #endif @@ -38,6 +45,21 @@ public class ApplicationInformation public int ProcessorCount { get; } = Environment.ProcessorCount; public bool IsAttached { get; } = Debugger.IsAttached; + /// + /// Reduct `+HASH` suffix from InformationalVersion. + ///
Example1: 1.0.0+1234567890abcdefg -> 1.0.0 + ///
Example2: 1.0.0 -> 1.0.0 + ///
+ /// + /// + private static string? RemoveHashFromVersion(string? version) + { + if (string.IsNullOrEmpty(version)) return version; + var span = version.AsSpan(); + var position = span.IndexOf('+'); + return position == -1 ? version : span[..position].ToString(); + } + public class CpuInformation { public static CpuInformation Current { get; } = new CpuInformation(); diff --git a/perf/BenchmarkApp/PerformanceTest.Shared/IPerfTestControlService.cs b/perf/BenchmarkApp/PerformanceTest.Shared/IPerfTestControlService.cs index 982804142..a4c09d8d4 100644 --- a/perf/BenchmarkApp/PerformanceTest.Shared/IPerfTestControlService.cs +++ b/perf/BenchmarkApp/PerformanceTest.Shared/IPerfTestControlService.cs @@ -8,6 +8,7 @@ namespace PerformanceTest.Shared; public interface IPerfTestControlService : IService { UnaryResult GetServerInformationAsync(); + UnaryResult<(string serverMagicOnionVersion, bool enableLatestTag)> ExchangeMagicOnionVersionTagAsync(string? clientMagicOnionVersion, bool isLatestMagicOnionVersion); UnaryResult SetMemoryProfilerCollectAllocationsAsync(bool enable); UnaryResult CreateMemoryProfilerSnapshotAsync(string name); @@ -18,6 +19,8 @@ public interface IPerfTestControlService : IService public partial class ServerInformation { public string MachineName { get; set; } + public string? BenchmarkerVersion { get; set; } + public bool? IsLatestMagicOnion { get; } public string? MagicOnionVersion { get; } public string? GrpcNetVersion { get; } public string? MessagePackVersion { get; } @@ -32,9 +35,11 @@ public partial class ServerInformation public int ProcessorCount { get; } public bool IsAttached { get; } - public ServerInformation(string machineName, string? magicOnionVersion, string? grpcNetVersion, string? messagePackVersion, string? memoryPackVersion, bool isReleaseBuild, string frameworkDescription, string osDescription, Architecture osArchitecture, Architecture processArchitecture, string cpuModelName, bool isServerGC, int processorCount, bool isAttached) + public ServerInformation(string machineName, string? benchmarkerVersion, bool? isLatestMagicOnion, string? magicOnionVersion, string? grpcNetVersion, string? messagePackVersion, string? memoryPackVersion, bool isReleaseBuild, string frameworkDescription, string osDescription, Architecture osArchitecture, Architecture processArchitecture, string cpuModelName, bool isServerGC, int processorCount, bool isAttached) { MachineName = machineName; + BenchmarkerVersion = benchmarkerVersion; + IsLatestMagicOnion = isLatestMagicOnion; MagicOnionVersion = magicOnionVersion; GrpcNetVersion = grpcNetVersion; MessagePackVersion = messagePackVersion; diff --git a/perf/BenchmarkApp/PerformanceTest.Shared/MagicOnionIsLatestAttirbute.cs b/perf/BenchmarkApp/PerformanceTest.Shared/MagicOnionIsLatestAttirbute.cs new file mode 100644 index 000000000..74c154f8c --- /dev/null +++ b/perf/BenchmarkApp/PerformanceTest.Shared/MagicOnionIsLatestAttirbute.cs @@ -0,0 +1,6 @@ +namespace PerformanceTest.Shared; + +public class MagicOnionIsLatestAttirbute(string isLatest) : Attribute +{ + public bool IsLatest { get; } = string.IsNullOrWhiteSpace(isLatest); +} diff --git a/perf/BenchmarkApp/PerformanceTest.Shared/Reporting/DatadogMetricsRecorder.cs b/perf/BenchmarkApp/PerformanceTest.Shared/Reporting/DatadogMetricsRecorder.cs index 3db9797c0..162714728 100644 --- a/perf/BenchmarkApp/PerformanceTest.Shared/Reporting/DatadogMetricsRecorder.cs +++ b/perf/BenchmarkApp/PerformanceTest.Shared/Reporting/DatadogMetricsRecorder.cs @@ -7,11 +7,18 @@ namespace PerformanceTest.Shared.Reporting; public class DatadogMetricsRecorder { + // format should be `CLIENTxSERVER` Versions. + public static string MagicOnionVersions = ""; + public static bool EnableLatestTag = false; + public string TagBranch { get; } public string TagLegend { get; } public string TagStreams { get; } public string TagProtocol { get; } public string TagSerialization { get; } + public string TagMagicOnion => MagicOnionVersions; + public string TagLatestMagicOnion { get; } = "latestxlatest"; + private readonly JsonSerializerOptions jsonSerializerOptions; private readonly TimeProvider timeProvider; private readonly HttpClient client; diff --git a/perf/BenchmarkApp/configs/issue.yaml b/perf/BenchmarkApp/configs/issue.yaml index 5d7ee7624..9579a2afb 100644 --- a/perf/BenchmarkApp/configs/issue.yaml +++ b/perf/BenchmarkApp/configs/issue.yaml @@ -5,9 +5,9 @@ dotnet-version: 8.0 benchmark-expire-min: 15 benchmark-timeout-min: 10 benchmark-client-run-script-path: ".github/scripts/benchmark-client-run.sh" -benchmark-client-run-script-args: '--args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}"' +benchmark-client-run-script-args: '--run-args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsClient }}"' benchmark-server-run-script-path: ".github/scripts/benchmark-server-run.sh" -benchmark-server-run-script-args: '--args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}"' +benchmark-server-run-script-args: '--run-args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsServer }}"' benchmark-server-stop-script-path: ".github/scripts/benchmark-server-stop.sh" jobs: # h2c diff --git a/perf/BenchmarkApp/configs/schedule.yaml b/perf/BenchmarkApp/configs/schedule.yaml index 4aeb42ad0..c2754adac 100644 --- a/perf/BenchmarkApp/configs/schedule.yaml +++ b/perf/BenchmarkApp/configs/schedule.yaml @@ -5,9 +5,9 @@ dotnet-version: 8.0 benchmark-expire-min: 15 benchmark-timeout-min: 10 benchmark-client-run-script-path: ".github/scripts/benchmark-client-run.sh" -benchmark-client-run-script-args: '--args "-u http://${BENCHMARK_SERVER_NAME}:5000 -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}"' +benchmark-client-run-script-args: '--run-args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsClient }}"' benchmark-server-run-script-path: ".github/scripts/benchmark-server-run.sh" -benchmark-server-run-script-args: '--args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}"' +benchmark-server-run-script-args: '--run-args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsServer }}"' benchmark-server-stop-script-path: ".github/scripts/benchmark-server-stop.sh" jobs: ##### MessagePack ##### @@ -168,3 +168,67 @@ jobs: channels: 28 streams: 70 serialization: memorypack + ##### Fixed ClientVersion ##### + # h2c + - tags: legend:messagepack-h2c-linux,streams:1x1,protocol:h2c,serialization:messagepack + protocol: h2c + channels: 1 + streams: 1 + serialization: messagepack + buildArgsClient: --p:UseNuGetClient=6.1.4 + - tags: legend:messagepack-h2c-linux,streams:1x28,protocol:h2c,serialization:messagepack + protocol: h2c + channels: 28 + streams: 1 + serialization: messagepack + buildArgsClient: --p:UseNuGetClient=6.1.4 + - tags: legend:messagepack-h2c-linux,streams:28x1,protocol:h2c,serialization:messagepack + protocol: h2c + channels: 1 + streams: 28 + serialization: messagepack + buildArgsClient: --p:UseNuGetClient=6.1.4 + - tags: legend:messagepack-h2c-linux,streams:70x1,protocol:h2c,serialization:messagepack + protocol: h2c + channels: 1 + streams: 70 + serialization: messagepack + buildArgsClient: --p:UseNuGetClient=6.1.4 + - tags: legend:messagepack-h2c-linux,streams:70x28,protocol:h2c,serialization:messagepack + protocol: h2c + channels: 28 + streams: 70 + serialization: messagepack + buildArgsClient: --p:UseNuGetClient=6.1.4 + ##### Fixed ServerVersion ##### + # h2c + - tags: legend:messagepack-h2c-linux,streams:1x1,protocol:h2c,serialization:messagepack + protocol: h2c + channels: 1 + streams: 1 + serialization: messagepack + buildArgsServer: --p:UseNuGetServer=6.1.4 + - tags: legend:messagepack-h2c-linux,streams:1x28,protocol:h2c,serialization:messagepack + protocol: h2c + channels: 28 + streams: 1 + serialization: messagepack + buildArgsServer: --p:UseNuGetServer=6.1.4 + - tags: legend:messagepack-h2c-linux,streams:28x1,protocol:h2c,serialization:messagepack + protocol: h2c + channels: 1 + streams: 28 + serialization: messagepack + buildArgsServer: --p:UseNuGetServer=6.1.4 + - tags: legend:messagepack-h2c-linux,streams:70x1,protocol:h2c,serialization:messagepack + protocol: h2c + channels: 1 + streams: 70 + serialization: messagepack + buildArgsServer: --p:UseNuGetServer=6.1.4 + - tags: legend:messagepack-h2c-linux,streams:70x28,protocol:h2c,serialization:messagepack + protocol: h2c + channels: 28 + streams: 70 + serialization: messagepack + buildArgsServer: --p:UseNuGetServer=6.1.4 diff --git a/perf/BenchmarkApp/configs/workflow_dispatch_memorypack_h2.yaml b/perf/BenchmarkApp/configs/workflow_dispatch_memorypack_h2.yaml index 7bbaecf73..ebfeaebb9 100644 --- a/perf/BenchmarkApp/configs/workflow_dispatch_memorypack_h2.yaml +++ b/perf/BenchmarkApp/configs/workflow_dispatch_memorypack_h2.yaml @@ -5,9 +5,9 @@ dotnet-version: 8.0 benchmark-expire-min: 15 benchmark-timeout-min: 10 benchmark-client-run-script-path: ".github/scripts/benchmark-client-run.sh" -benchmark-client-run-script-args: '--args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}"' +benchmark-client-run-script-args: '--run-args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsClient }}"' benchmark-server-run-script-path: ".github/scripts/benchmark-server-run.sh" -benchmark-server-run-script-args: '--args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}"' +benchmark-server-run-script-args: '--run-args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsServer }}"' benchmark-server-stop-script-path: ".github/scripts/benchmark-server-stop.sh" jobs: # h2c diff --git a/perf/BenchmarkApp/configs/workflow_dispatch_memorypack_h2c.yaml b/perf/BenchmarkApp/configs/workflow_dispatch_memorypack_h2c.yaml index e0f7ad266..deac9c514 100644 --- a/perf/BenchmarkApp/configs/workflow_dispatch_memorypack_h2c.yaml +++ b/perf/BenchmarkApp/configs/workflow_dispatch_memorypack_h2c.yaml @@ -5,9 +5,9 @@ dotnet-version: 8.0 benchmark-expire-min: 15 benchmark-timeout-min: 10 benchmark-client-run-script-path: ".github/scripts/benchmark-client-run.sh" -benchmark-client-run-script-args: '--args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}"' +benchmark-client-run-script-args: '--run-args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsClient }}"' benchmark-server-run-script-path: ".github/scripts/benchmark-server-run.sh" -benchmark-server-run-script-args: '--args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}"' +benchmark-server-run-script-args: '--run-args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsServer }}"' benchmark-server-stop-script-path: ".github/scripts/benchmark-server-stop.sh" jobs: # h2c diff --git a/perf/BenchmarkApp/configs/workflow_dispatch_memorypack_h3.yaml b/perf/BenchmarkApp/configs/workflow_dispatch_memorypack_h3.yaml index ecb3206b9..1bc740caa 100644 --- a/perf/BenchmarkApp/configs/workflow_dispatch_memorypack_h3.yaml +++ b/perf/BenchmarkApp/configs/workflow_dispatch_memorypack_h3.yaml @@ -5,9 +5,9 @@ dotnet-version: 8.0 benchmark-expire-min: 15 benchmark-timeout-min: 10 benchmark-client-run-script-path: ".github/scripts/benchmark-client-run.sh" -benchmark-client-run-script-args: '--args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}"' +benchmark-client-run-script-args: '--run-args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsClient }}"' benchmark-server-run-script-path: ".github/scripts/benchmark-server-run.sh" -benchmark-server-run-script-args: '--args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}"' +benchmark-server-run-script-args: '--run-args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsServer }}"' benchmark-server-stop-script-path: ".github/scripts/benchmark-server-stop.sh" jobs: # h2c diff --git a/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2.yaml b/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2.yaml index 469ff4f85..384edfb75 100644 --- a/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2.yaml +++ b/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2.yaml @@ -5,9 +5,9 @@ dotnet-version: 8.0 benchmark-expire-min: 15 benchmark-timeout-min: 10 benchmark-client-run-script-path: ".github/scripts/benchmark-client-run.sh" -benchmark-client-run-script-args: '--args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}"' +benchmark-client-run-script-args: '--run-args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsClient }}"' benchmark-server-run-script-path: ".github/scripts/benchmark-server-run.sh" -benchmark-server-run-script-args: '--args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}"' +benchmark-server-run-script-args: '--run-args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsServer }}"' benchmark-server-stop-script-path: ".github/scripts/benchmark-server-stop.sh" jobs: # h2c diff --git a/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2_nugetclient.yaml b/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2_nugetclient.yaml new file mode 100644 index 000000000..1a4d8af49 --- /dev/null +++ b/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2_nugetclient.yaml @@ -0,0 +1,37 @@ +# template: https://github.com/Cysharp/Actions/tree/main/.github/scripts/_template_benchmark_config.yaml +# config2args script: https://github.com/Cysharp/Actions/tree/main/.github/scripts/benchmark_config2args.sh +apt-tools: "" +dotnet-version: 8.0 +benchmark-expire-min: 15 +benchmark-timeout-min: 10 +benchmark-client-run-script-path: ".github/scripts/benchmark-client-run.sh" +benchmark-client-run-script-args: '--run-args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsClient }}"' +benchmark-server-run-script-path: ".github/scripts/benchmark-server-run.sh" +benchmark-server-run-script-args: '--run-args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsServer }}"' +benchmark-server-stop-script-path: ".github/scripts/benchmark-server-stop.sh" +jobs: + # h2 + - tags: legend:messagepack-h2-linux,streams:1x1,protocol:h2,serialization:messagepack + protocol: h2 + channels: 1 + streams: 1 + serialization: messagepack + buildArgsClient: --p:UseNuGetClient=6.1.4 + - tags: legend:messagepack-h2-linux,streams:1x28,protocol:h2,serialization:messagepack + protocol: h2 + channels: 28 + streams: 1 + serialization: messagepack + buildArgsClient: --p:UseNuGetClient=6.1.4 + - tags: legend:messagepack-h2-linux,streams:70x1,protocol:h2,serialization:messagepack + protocol: h2 + channels: 1 + streams: 70 + serialization: messagepack + buildArgsClient: --p:UseNuGetClient=6.1.4 + - tags: legend:messagepack-h2-linux,streams:70x28,protocol:h2,serialization:messagepack + protocol: h2 + channels: 28 + streams: 70 + serialization: messagepack + buildArgsClient: --p:UseNuGetClient=6.1.4 diff --git a/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2_nugetserver.yaml b/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2_nugetserver.yaml new file mode 100644 index 000000000..c3330a64a --- /dev/null +++ b/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2_nugetserver.yaml @@ -0,0 +1,37 @@ +# template: https://github.com/Cysharp/Actions/tree/main/.github/scripts/_template_benchmark_config.yaml +# config2args script: https://github.com/Cysharp/Actions/tree/main/.github/scripts/benchmark_config2args.sh +apt-tools: "" +dotnet-version: 8.0 +benchmark-expire-min: 15 +benchmark-timeout-min: 10 +benchmark-client-run-script-path: ".github/scripts/benchmark-client-run.sh" +benchmark-client-run-script-args: '--run-args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsClient }}"' +benchmark-server-run-script-path: ".github/scripts/benchmark-server-run.sh" +benchmark-server-run-script-args: '--run-args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsServer }}"' +benchmark-server-stop-script-path: ".github/scripts/benchmark-server-stop.sh" +jobs: + # h2 + - tags: legend:messagepack-h2-linux,streams:1x1,protocol:h2,serialization:messagepack + protocol: h2 + channels: 1 + streams: 1 + serialization: messagepack + buildArgsServer: --p:UseNuGetServer=6.1.4 + - tags: legend:messagepack-h2-linux,streams:1x28,protocol:h2,serialization:messagepack + protocol: h2 + channels: 28 + streams: 1 + serialization: messagepack + buildArgsServer: --p:UseNuGetServer=6.1.4 + - tags: legend:messagepack-h2-linux,streams:70x1,protocol:h2,serialization:messagepack + protocol: h2 + channels: 1 + streams: 70 + serialization: messagepack + buildArgsServer: --p:UseNuGetServer=6.1.4 + - tags: legend:messagepack-h2-linux,streams:70x28,protocol:h2,serialization:messagepack + protocol: h2 + channels: 28 + streams: 70 + serialization: messagepack + buildArgsServer: --p:UseNuGetServer=6.1.4 diff --git a/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2c.yaml b/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2c.yaml index 3c5b6a7c4..f11fba77e 100644 --- a/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2c.yaml +++ b/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2c.yaml @@ -5,9 +5,9 @@ dotnet-version: 8.0 benchmark-expire-min: 15 benchmark-timeout-min: 10 benchmark-client-run-script-path: ".github/scripts/benchmark-client-run.sh" -benchmark-client-run-script-args: '--args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}"' +benchmark-client-run-script-args: '--run-args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsClient }}"' benchmark-server-run-script-path: ".github/scripts/benchmark-server-run.sh" -benchmark-server-run-script-args: '--args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}"' +benchmark-server-run-script-args: '--run-args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsServer }}"' benchmark-server-stop-script-path: ".github/scripts/benchmark-server-stop.sh" jobs: # h2c diff --git a/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2c_nugetclient.yaml b/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2c_nugetclient.yaml new file mode 100644 index 000000000..97ac82102 --- /dev/null +++ b/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2c_nugetclient.yaml @@ -0,0 +1,37 @@ +# template: https://github.com/Cysharp/Actions/tree/main/.github/scripts/_template_benchmark_config.yaml +# config2args script: https://github.com/Cysharp/Actions/tree/main/.github/scripts/benchmark_config2args.sh +apt-tools: "" +dotnet-version: 8.0 +benchmark-expire-min: 15 +benchmark-timeout-min: 10 +benchmark-client-run-script-path: ".github/scripts/benchmark-client-run.sh" +benchmark-client-run-script-args: '--run-args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsClient }}"' +benchmark-server-run-script-path: ".github/scripts/benchmark-server-run.sh" +benchmark-server-run-script-args: '--run-args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsServer }}"' +benchmark-server-stop-script-path: ".github/scripts/benchmark-server-stop.sh" +jobs: + # h2c + - tags: legend:messagepack-h2c-linux,streams:1x1,protocol:h2c,serialization:messagepack + protocol: h2c + channels: 1 + streams: 1 + serialization: messagepack + buildArgsClient: --p:UseNuGetClient=6.1.4 + - tags: legend:messagepack-h2c-linux,streams:1x28,protocol:h2c,serialization:messagepack + protocol: h2c + channels: 28 + streams: 1 + serialization: messagepack + buildArgsClient: --p:UseNuGetClient=6.1.4 + - tags: legend:messagepack-h2c-linux,streams:70x1,protocol:h2c,serialization:messagepack + protocol: h2c + channels: 1 + streams: 70 + serialization: messagepack + buildArgsClient: --p:UseNuGetClient=6.1.4 + - tags: legend:messagepack-h2c-linux,streams:70x28,protocol:h2c,serialization:messagepack + protocol: h2c + channels: 28 + streams: 70 + serialization: messagepack + buildArgsClient: --p:UseNuGetClient=6.1.4 diff --git a/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2c_nugetserver.yaml b/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2c_nugetserver.yaml new file mode 100644 index 000000000..8badce56d --- /dev/null +++ b/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h2c_nugetserver.yaml @@ -0,0 +1,37 @@ +# template: https://github.com/Cysharp/Actions/tree/main/.github/scripts/_template_benchmark_config.yaml +# config2args script: https://github.com/Cysharp/Actions/tree/main/.github/scripts/benchmark_config2args.sh +apt-tools: "" +dotnet-version: 8.0 +benchmark-expire-min: 15 +benchmark-timeout-min: 10 +benchmark-client-run-script-path: ".github/scripts/benchmark-client-run.sh" +benchmark-client-run-script-args: '--run-args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsClient }}"' +benchmark-server-run-script-path: ".github/scripts/benchmark-server-run.sh" +benchmark-server-run-script-args: '--run-args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsServer }}"' +benchmark-server-stop-script-path: ".github/scripts/benchmark-server-stop.sh" +jobs: + # h2c + - tags: legend:messagepack-h2c-linux,streams:1x1,protocol:h2c,serialization:messagepack + protocol: h2c + channels: 1 + streams: 1 + serialization: messagepack + buildArgsServer: --p:UseNuGetServer=6.1.4 + - tags: legend:messagepack-h2c-linux,streams:1x28,protocol:h2c,serialization:messagepack + protocol: h2c + channels: 28 + streams: 1 + serialization: messagepack + buildArgsServer: --p:UseNuGetServer=6.1.4 + - tags: legend:messagepack-h2c-linux,streams:70x1,protocol:h2c,serialization:messagepack + protocol: h2c + channels: 1 + streams: 70 + serialization: messagepack + buildArgsServer: --p:UseNuGetServer=6.1.4 + - tags: legend:messagepack-h2c-linux,streams:70x28,protocol:h2c,serialization:messagepack + protocol: h2c + channels: 28 + streams: 70 + serialization: messagepack + buildArgsServer: --p:UseNuGetServer=6.1.4 diff --git a/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h3.yaml b/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h3.yaml index ecac63aa7..4c0c2eb5a 100644 --- a/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h3.yaml +++ b/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h3.yaml @@ -5,9 +5,9 @@ dotnet-version: 8.0 benchmark-expire-min: 15 benchmark-timeout-min: 10 benchmark-client-run-script-path: ".github/scripts/benchmark-client-run.sh" -benchmark-client-run-script-args: '--args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}"' +benchmark-client-run-script-args: '--run-args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsClient }}"' benchmark-server-run-script-path: ".github/scripts/benchmark-server-run.sh" -benchmark-server-run-script-args: '--args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}"' +benchmark-server-run-script-args: '--run-args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsServer }}"' benchmark-server-stop-script-path: ".github/scripts/benchmark-server-stop.sh" jobs: # h2c diff --git a/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h3_nugetclient.yaml b/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h3_nugetclient.yaml new file mode 100644 index 000000000..42c9a5a6f --- /dev/null +++ b/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h3_nugetclient.yaml @@ -0,0 +1,37 @@ +# template: https://github.com/Cysharp/Actions/tree/main/.github/scripts/_template_benchmark_config.yaml +# config2args script: https://github.com/Cysharp/Actions/tree/main/.github/scripts/benchmark_config2args.sh +apt-tools: "" +dotnet-version: 8.0 +benchmark-expire-min: 15 +benchmark-timeout-min: 10 +benchmark-client-run-script-path: ".github/scripts/benchmark-client-run.sh" +benchmark-client-run-script-args: '--run-args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsClient }}"' +benchmark-server-run-script-path: ".github/scripts/benchmark-server-run.sh" +benchmark-server-run-script-args: '--run-args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsServer }}"' +benchmark-server-stop-script-path: ".github/scripts/benchmark-server-stop.sh" +jobs: + # h3 + - tags: legend:messagepack-h3-linux,streams:1x1,protocol:h3,serialization:messagepack + protocol: h3 + channels: 1 + streams: 1 + serialization: messagepack + buildArgsClient: --p:UseNuGetClient=6.1.4 + - tags: legend:messagepack-h3-linux,streams:1x28,protocol:h3,serialization:messagepack + protocol: h3 + channels: 28 + streams: 1 + serialization: messagepack + buildArgsClient: --p:UseNuGetClient=6.1.4 + - tags: legend:messagepack-h3-linux,streams:70x1,protocol:h3,serialization:messagepack + protocol: h3 + channels: 1 + streams: 70 + serialization: messagepack + buildArgsClient: --p:UseNuGetClient=6.1.4 + - tags: legend:messagepack-h3-linux,streams:70x28,protocol:h3,serialization:messagepack + protocol: h3 + channels: 28 + streams: 70 + serialization: messagepack + buildArgsClient: --p:UseNuGetClient=6.1.4 diff --git a/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h3_nugetserver.yaml b/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h3_nugetserver.yaml new file mode 100644 index 000000000..3144c81e7 --- /dev/null +++ b/perf/BenchmarkApp/configs/workflow_dispatch_messagepack_h3_nugetserver.yaml @@ -0,0 +1,37 @@ +# template: https://github.com/Cysharp/Actions/tree/main/.github/scripts/_template_benchmark_config.yaml +# config2args script: https://github.com/Cysharp/Actions/tree/main/.github/scripts/benchmark_config2args.sh +apt-tools: "" +dotnet-version: 8.0 +benchmark-expire-min: 15 +benchmark-timeout-min: 10 +benchmark-client-run-script-path: ".github/scripts/benchmark-client-run.sh" +benchmark-client-run-script-args: '--run-args "-u http://${BENCHMARK_SERVER_NAME}:5000 --protocol {{ protocol }} -s CI --rounds 3 --channels {{ channels }} --streams {{ streams }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsClient }}"' +benchmark-server-run-script-path: ".github/scripts/benchmark-server-run.sh" +benchmark-server-run-script-args: '--run-args "-u http://0.0.0.0:5000 --protocol {{ protocol }} --serialization {{ serialization }} --validate true --tags {{ tags }}" --build-args "{{ buildArgsServer }}"' +benchmark-server-stop-script-path: ".github/scripts/benchmark-server-stop.sh" +jobs: + # h3 + - tags: legend:messagepack-h3-linux,streams:1x1,protocol:h3,serialization:messagepack + protocol: h3 + channels: 1 + streams: 1 + serialization: messagepack + buildArgsServer: --p:UseNuGetServer=6.1.4 + - tags: legend:messagepack-h3-linux,streams:1x28,protocol:h3,serialization:messagepack + protocol: h3 + channels: 28 + streams: 1 + serialization: messagepack + buildArgsServer: --p:UseNuGetServer=6.1.4 + - tags: legend:messagepack-h3-linux,streams:70x1,protocol:h3,serialization:messagepack + protocol: h3 + channels: 1 + streams: 70 + serialization: messagepack + buildArgsServer: --p:UseNuGetServer=6.1.4 + - tags: legend:messagepack-h3-linux,streams:70x28,protocol:h3,serialization:messagepack + protocol: h3 + channels: 28 + streams: 70 + serialization: messagepack + buildArgsServer: --p:UseNuGetServer=6.1.4