Skip to content

better API safety

better API safety #548

Workflow file for this run

name: bench
on:
push:
branches:
- main
workflow_dispatch:
inputs:
selector:
description: 'Benchmark selector'
required: false
default: 'Kyo'
warmupIterations:
description: 'Warmup iterations'
required: false
default: '13'
measurementIterations:
description: 'Measurement iterations'
required: false
default: '5'
iterationTime:
description: 'Iteration time'
required: false
default: '1'
forks:
description: 'Number of forks'
required: false
default: '1'
threads:
description: 'Number of threads'
required: false
default: '1'
profileEvents:
description: 'Profile events'
required: false
default: 'alloc,cpu'
jobs:
bench:
name: bench
runs-on: bench
timeout-minutes: 90
env:
SE: ${{ github.event.inputs.selector || 'Kyo' }}
WI: ${{ github.event.inputs.warmupIterations || '13' }}
MI: ${{ github.event.inputs.measurementIterations || '5' }}
IT: ${{ github.event.inputs.iterationTime || '1' }}
FK: ${{ github.event.inputs.forks || '1' }}
TH: ${{ github.event.inputs.threads || '1' }}
PE: ${{ github.event.inputs.profileEvents || 'alloc,cpu' }}
steps:
- uses: actions/[email protected]
with:
fetch-depth: 0
- uses: olafurpg/setup-scala@v13
with:
java-version: [email protected]
- name: install async-profiler
run: |
cd /home/runner
wget https://github.com/jvm-profiling-tools/async-profiler/releases/download/v2.9/async-profiler-2.9-linux-x64.tar.gz
tar -xvzf async-profiler-2.9-linux-x64.tar.gz
sudo mkdir -p /usr/java/packages/lib/
sudo cp async-profiler-2.9-linux-x64/build/libasyncProfiler.so /usr/java/packages/lib/
sudo sysctl kernel.perf_event_paranoid=1
sudo sysctl kernel.kptr_restrict=0
- name: run
run: |
IFS=', ' read -r -a array <<< "$PE"
for EVENT in "${array[@]}"
do
ESCAPED_EVENT=$(printf '%q' "$EVENT")
sbt "kyo-bench/jmh:clean;kyo-bench/jmh:run -wi $WI -i $MI -r $IT -w $IT -f $FK -t $TH -foe true -prof \"async:event=$ESCAPED_EVENT;output=flamegraph\" $SE"
done
sbt "kyo-bench/jmh:clean;kyo-bench/jmh:run -wi $WI -i $MI -r $IT -w $IT -f $FK -t $TH -foe true -prof gc -rf json $SE"
- name: prepare results
run: |
short_sha=$(echo "${{ github.sha }}" | cut -c 1-7)
mkdir -p output/
cp -r kyo-bench/.jvm/jmh-result.json output/#${short_sha}-jmh-result.json
cp -r kyo-bench/.jvm/kyo.bench.* output/
rm -rf output/**/*reverse.html
for file in $(find output -name "*.html"); do
newfile=$(echo $file | sed 's/\([^.]*\)-.*flame-\([^-]*\)-forward.html/\1-\2.html/')
if [ "$file" != "$newfile" ]; then
mv "$file" "$newfile"
fi
done
for file in $(find output -name "*.html"); do
new_name="${short_sha}-$(basename "$file")"
mv "$file" "$(dirname "$file")/$new_name"
done
ls output/
- name: publish results
id: publish-results
uses: actions/github-script@v5
with:
github-token: ${{ secrets.GIST_PAT }}
script: |
const fs = require('fs').promises;
const path = require('path');
async function getFiles(dir) {
const dirents = await fs.readdir(dir, { withFileTypes: true });
const files = await Promise.all(dirents.map((dirent) => {
const res = path.resolve(dir, dirent.name);
return dirent.isDirectory() ? getFiles(res) : res;
}));
return Array.prototype.concat(...files);
}
let gistFiles = {};
const files = await getFiles('output/');
for (const file of files) {
const content = await fs.readFile(file, 'utf-8');
const relativePath = path.relative('output/', file);
let gistFileName = relativePath.split(path.sep).join('-');
gistFiles[gistFileName] = { content: content };
}
const gist = await github.rest.gists.create({
files: gistFiles,
public: true
});
gistUrl = gist.data.html_url;
fs.appendFile(process.env.GITHUB_ENV, `GIST_URL=${gistUrl}\n`, 'utf8');
- name: Check Build Cache for Index URL
id: check-cache
uses: actions/cache@v2
with:
path: jmh-github-action-index.txt
key: index-url
- name: Get commit message
id: get-commit-message
run: |
COMMIT_MESSAGE="$(git log --format=%B -n 1 ${{ github.sha }})"
echo "COMMIT_MESSAGE=${COMMIT_MESSAGE}" >> $GITHUB_ENV
- name: Update Index
id: update-index
uses: actions/github-script@v5
with:
github-token: ${{ secrets.GIST_PAT }}
script: |
const indexFileName = 'jmh-github-action.csv';
const runUrl = `https://github.com/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`;
const commitUrl = `https://github.com/${process.env.GITHUB_REPOSITORY}/commit/${context.sha}`;
const commitMessage = process.env.COMMIT_MESSAGE.replace(/,/g, '\\,');
const selector = process.env.SE;
const currentDateTime = new Date();
const gistUrl = process.env.GIST_URL;
const timestamp = currentDateTime.toLocaleString('en-US', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
hour12: false
}).replace(',', '');
let indexGist;
let indexUrl = core.getState('index_url');
async function getGists(page = 1, perPage = 100) {
const { data: gistList } = await github.rest.gists.list({ page, per_page: perPage });
return gistList;
}
async function findIndexGist() {
let page = 1;
let gists;
do {
gists = await getGists(page);
indexGist = gists.find(gist => gist.files[indexFileName]);
page++;
} while (!indexGist && gists.length > 0);
return indexGist;
}
const https = require('https');
async function updateIndexGist() {
if (indexGist) {
const indexFile = indexGist.files[indexFileName];
let fileContent = '';
if (indexFile && indexFile.raw_url) {
fileContent = await new Promise((resolve, reject) => {
https.get(indexFile.raw_url, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve(data);
});
}).on('error', (err) => {
console.log("Error: " + err.message);
reject(err);
});
});
}
const newIndexContent = (fileContent ? fileContent + "\n" : "") + `${commitUrl},${commitMessage},${selector},${runUrl},${gistUrl}`;
await github.rest.gists.update({
gist_id: indexGist.id,
files: {
[indexFileName]: {
content: newIndexContent
}
}
});
} else {
const header = "commit_url,commit_message,selector,run,gist";
const newIndexContent = `${header}\n${commitUrl},${commitMessage},${selector},${runUrl},${gistUrl}`;
const newGist = await github.rest.gists.create({
files: {
[indexFileName]: {
content: newIndexContent
}
},
public: true
});
indexUrl = newGist.data.html_url;
core.saveState('index_url', indexUrl);
}
}
if (indexUrl) {
const indexGistId = indexUrl.split('/').pop();
indexGist = await github.rest.gists.get({ gist_id: indexGistId });
}
if (indexGist) {
await updateIndexGist();
} else {
indexGist = await findIndexGist();
await updateIndexGist();
}