Skip to content

Commit

Permalink
Merge pull request #801 from Cysharp/benchmark
Browse files Browse the repository at this point in the history
ci: add benchmark workflow
  • Loading branch information
mayuki authored Jul 9, 2024
2 parents 764456c + ea2daef commit 21b14de
Show file tree
Hide file tree
Showing 5 changed files with 248 additions and 1 deletion.
93 changes: 93 additions & 0 deletions .github/scripts/run-benchmark-client.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/bin/bash
set -euo pipefail

# benchmark over ssh
#
# MagicOnion Client
# $ ssh -o StrictHostKeyChecking=accept-new -i ~/.ssh/id_ed25519 [email protected] 'bash -s -- --args "-u http://${BENCHMARK_SERVER_NAME}:5000 -s streaminghub --channels 1 --streams 1"' < ./scripts/run-benchmark.sh
# $ echo $?

function usage {
echo "usage: $(basename $0) --args <string> [options]"
echo "Required:"
echo " --args string Arguments to pass when running the built binary (default: \"\")"
echo "Options:"
echo " --help Show this help message"
}

while [ $# -gt 0 ]; do
case $1 in
# required
--args) _ARGS=$2; shift 2; ;;
# optional
--help) usage; exit 1; ;;
*) shift ;;
esac
done

function print() {
echo ""
echo "$*"
}

# 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)"

# is dotnet installed?
print "# Show installed dotnet sdk versions"
echo "dotnet sdk versions (list): $(dotnet --list-sdks)"
echo "dotnet sdk version (default): $(dotnet --version)"

# 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

# run dotnet app
print "# Run $full_process_path $args"
pushd "$output_dir"
# run foreground
"./$binary_name" $args
popd
103 changes: 103 additions & 0 deletions .github/scripts/run-benchmark-server.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#!/bin/bash
set -euo pipefail

# benchmark over ssh
#
# MagicOnion Server
# ssh -o StrictHostKeyChecking=accept-new -i ~/.ssh/id_ed25519 [email protected] 'bash -s -- ' < ./scripts/run-server
# $ echo $?

function usage {
echo "usage: $(basename $0) [options]"
echo "Options:"
echo " --help Show this help message"
}

while [ $# -gt 0 ]; do
case $1 in
--help) usage; exit 1; ;;
*) shift ;;
esac
done

function print() {
echo ""
echo "$*"
}

# parameter setup
repo="MagicOnion"
build_config="Release"
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)"

# is dotnet installed?
print "# Show installed dotnet sdk versions"
echo "dotnet sdk versions (list): $(dotnet --list-sdks)"
echo "dotnet sdk version (default): $(dotnet --version)"

# 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

# run dotnet app
print "# Run $full_process_path"
pushd "$output_dir"
# run background https://stackoverflow.com/questions/29142/getting-ssh-to-execute-a-command-in-the-background-on-target-machine
nohup "./$binary_name" > "${stdoutfile}" 2> "${stderrfile}" < /dev/null &

# wait 10s will be enough to start the server or not
sleep 10s

# output stdout
cat "${stdoutfile}"

# output stderr
if [[ "$(stat -c%s "$stderrfile")" -ne "0" ]]; then
echo "Error found when running the server."
cat "${stderrfile}"
exit 1
fi
popd
44 changes: 44 additions & 0 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Benchmark

on:
issue_comment:
types: [created]
workflow_dispatch:

permissions:
contents: read
id-token: write

jobs:
prepare:
outputs:
branch: ${{ steps.get-branch.outputs.name }}
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- name: Get branch name
id: get-branch
run: |
if [[ "${{ github.event_name}}" == "issue_comment" && "${{ github.event.issue.pull_request.html_url }}" != "" ]]; then
# issue_comment (pull_request)
branch=$(gh pr view "${{ github.event.issue.pull_request.html_url }}" --json headRefName | jq -r ".headRefName")
echo "name=${branch}" | tee -a "$GITHUB_OUTPUT"
else
# workflow_dispatch or issue_comment (issue)
echo "name=${{ github.ref_name }}" | tee -a "$GITHUB_OUTPUT"
fi
# run benchmark
benchmark:
needs: [prepare]
uses: Cysharp/Actions/.github/workflows/benchmark.yaml@main
with:
branch: ${{ needs.prepare.outputs.branch }}
dotnet-version: "8.0"
environment: benchmark
client-benchmark-script-path: ".github/scripts/run-benchmark-client.sh"
client-benchmark-script-args: "--args \"-u http://${BENCHMARK_SERVER_NAME}:5000 -s streaminghub --channels 1 --streams 1\""
server-benchmark-script-path: ".github/scripts/run-benchmark-server.sh"
server-benchmark-script-args: ""
secrets: inherit
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"launchBrowser": false,
"applicationUrl": "http://localhost:5000;https://localhost:5001",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
"ASPNETCORE_ENVIRONMENT": "Development",
"Kestrel__Endpoints__Grpc__Url": "http://localhost:5000"
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions perf/BenchmarkApp/PerformanceTest.Server/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http2"
},
"Endpoints": {
"Grpc": {
"Url": "http://+:5000",
"Protocols": "Http2"
}
}
}
}

0 comments on commit 21b14de

Please sign in to comment.