Skip to content

Commit 0ec409e

Browse files
committed
feat: add benchmark workflow for performance and memory usage
1 parent bec801a commit 0ec409e

File tree

1 file changed

+233
-0
lines changed

1 file changed

+233
-0
lines changed

.github/workflows/benchmark.yml

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
name: Benchmark
2+
3+
on:
4+
push:
5+
branches: [ "master" ]
6+
pull_request:
7+
branches: [ "master" ]
8+
workflow_dispatch:
9+
schedule:
10+
# Run benchmarks weekly on Sundays at 2 AM UTC
11+
- cron: '0 2 * * 0'
12+
13+
concurrency:
14+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
15+
cancel-in-progress: true
16+
17+
jobs:
18+
benchmark:
19+
name: Performance Benchmark
20+
runs-on: ubuntu-latest
21+
timeout-minutes: 30
22+
23+
steps:
24+
- name: Check out the repo
25+
uses: actions/checkout@v4
26+
with:
27+
fetch-depth: 0
28+
29+
- name: Install MetaCall Linux
30+
run: curl -sL https://raw.githubusercontent.com/metacall/install/master/install.sh | sh
31+
32+
- name: Install Rust
33+
uses: actions-rs/toolchain@v1
34+
with:
35+
toolchain: stable
36+
override: true
37+
components: rustfmt, clippy
38+
39+
- name: Install Node.js
40+
uses: actions/setup-node@v4
41+
with:
42+
node-version: '18'
43+
cache: 'npm'
44+
cache-dependency-path: tests/web-app/package-lock.json
45+
46+
- name: Install wrk (load testing tool)
47+
run: |
48+
sudo apt-get update
49+
sudo apt-get install -y wrk
50+
51+
- name: Build MetaSSR
52+
run: cargo build --release
53+
54+
- name: Setup benchmark test app
55+
working-directory: ./tests/web-app
56+
run: |
57+
npm install
58+
npm run build
59+
60+
- name: Start MetaSSR server
61+
working-directory: ./tests/web-app
62+
run: |
63+
npm run start &
64+
echo $! > metassr.pid
65+
sleep 10
66+
67+
- name: Warm up MetaSSR server
68+
run: |
69+
curl -s http://localhost:8080 > /dev/null
70+
sleep 2
71+
72+
- name: Benchmark MetaSSR
73+
run: |
74+
echo "=== MetaSSR Benchmark ===" > benchmark_results.txt
75+
wrk -t12 -c100 -d30s --latency http://localhost:8080 >> benchmark_results.txt
76+
echo "" >> benchmark_results.txt
77+
78+
- name: Benchmark MetaSSR (Light Load)
79+
run: |
80+
echo "=== MetaSSR Light Load (1 thread, 10 connections) ===" >> benchmark_results.txt
81+
wrk -t1 -c10 -d30s --latency http://localhost:8080 >> benchmark_results.txt
82+
echo "" >> benchmark_results.txt
83+
84+
- name: Benchmark MetaSSR (Medium Load)
85+
run: |
86+
echo "=== MetaSSR Medium Load (4 threads, 50 connections) ===" >> benchmark_results.txt
87+
wrk -t4 -c50 -d30s --latency http://localhost:8080 >> benchmark_results.txt
88+
echo "" >> benchmark_results.txt
89+
90+
- name: Benchmark MetaSSR (Heavy Load)
91+
run: |
92+
echo "=== MetaSSR Heavy Load (12 threads, 1000 connections) ===" >> benchmark_results.txt
93+
wrk -t12 -c1000 -d30s --latency http://localhost:8080 >> benchmark_results.txt
94+
echo "" >> benchmark_results.txt
95+
96+
- name: Benchmark MetaSSR (Sustained Load)
97+
run: |
98+
echo "=== MetaSSR Sustained Load (8 threads, 200 connections, 2 minutes) ===" >> benchmark_results.txt
99+
wrk -t8 -c200 -d120s --latency http://localhost:8080 >> benchmark_results.txt
100+
echo "" >> benchmark_results.txt
101+
102+
- name: Stop MetaSSR server
103+
working-directory: ./tests/web-app
104+
run: |
105+
if [ -f metassr.pid ]; then
106+
kill $(cat metassr.pid) || true
107+
rm metassr.pid
108+
fi
109+
sleep 5
110+
111+
- name: Install Python dependencies
112+
run: |
113+
pip install pandas matplotlib seaborn numpy
114+
115+
- name: Make scripts executable
116+
run: |
117+
chmod +x benchmarks/run-benchmarks.sh
118+
chmod +x benchmarks/benchmark.sh
119+
chmod +x benchmarks/analyze-benchmarks.py
120+
chmod +x benchmarks/move-results.sh
121+
122+
- name: Setup benchmark results directory
123+
run: |
124+
mkdir -p benchmark-results
125+
# Move any existing results from wrong location
126+
./benchmarks/move-results.sh
127+
128+
- name: Run comprehensive benchmarks
129+
run: |
130+
./benchmarks/run-benchmarks.sh --skip-build --analyze
131+
env:
132+
RESULTS_DIR: benchmark-results
133+
134+
- name: Generate PR benchmark summary
135+
run: |
136+
chmod +x benchmarks/generate-pr-summary.py
137+
python3 benchmarks/generate-pr-summary.py
138+
env:
139+
GITHUB_SHA: ${{ github.sha }}
140+
RUNNER_OS: ${{ runner.os }}
141+
142+
- name: Display results
143+
run: |
144+
echo "Benchmark completed successfully!"
145+
echo "=== PR Summary ==="
146+
cat pr_benchmark_summary.md
147+
148+
- name: Upload benchmark results
149+
uses: actions/upload-artifact@v4
150+
with:
151+
name: benchmark-results-${{ github.run_id }}
152+
path: |
153+
benchmark-results/
154+
benchmarks/benchmark-config.json
155+
retention-days: 30
156+
157+
- name: Comment benchmark results on PR
158+
if: github.event_name == 'pull_request'
159+
uses: actions/github-script@v7
160+
with:
161+
script: |
162+
const fs = require('fs');
163+
164+
try {
165+
const summary = fs.readFileSync('pr_benchmark_summary.md', 'utf8');
166+
167+
await github.rest.issues.createComment({
168+
issue_number: context.issue.number,
169+
owner: context.repo.owner,
170+
repo: context.repo.repo,
171+
body: summary
172+
});
173+
174+
console.log('Successfully posted benchmark results to PR');
175+
} catch (error) {
176+
console.error('Failed to post benchmark results:', error);
177+
}
178+
179+
memory-benchmark:
180+
name: Memory Usage Benchmark
181+
runs-on: ubuntu-latest
182+
timeout-minutes: 20
183+
184+
steps:
185+
- name: Check out the repo
186+
uses: actions/checkout@v4
187+
188+
- name: Install MetaCall Linux
189+
run: curl -sL https://raw.githubusercontent.com/metacall/install/master/install.sh | sh
190+
191+
- name: Install Rust
192+
uses: actions-rs/toolchain@v1
193+
with:
194+
toolchain: stable
195+
override: true
196+
197+
- name: Install Node.js
198+
uses: actions/setup-node@v4
199+
with:
200+
node-version: '18'
201+
202+
- name: Build MetaSSR
203+
run: cargo build --release
204+
205+
- name: Setup test app
206+
working-directory: ./tests/web-app
207+
run: |
208+
npm install
209+
npm run build
210+
211+
- name: Monitor MetaSSR memory usage
212+
working-directory: ./tests/web-app
213+
run: |
214+
npm run start &
215+
SERVER_PID=$!
216+
sleep 10
217+
218+
# Monitor memory for 60 seconds
219+
echo "timestamp,memory_mb" > memory_usage.csv
220+
for i in {1..60}; do
221+
memory=$(ps -o rss= -p $SERVER_PID | awk '{print $1/1024}')
222+
echo "$i,$memory" >> memory_usage.csv
223+
sleep 1
224+
done
225+
226+
kill $SERVER_PID
227+
228+
- name: Upload memory benchmark
229+
uses: actions/upload-artifact@v4
230+
with:
231+
name: memory-benchmark-${{ github.run_id }}
232+
path: tests/web-app/memory_usage.csv
233+
retention-days: 30

0 commit comments

Comments
 (0)