From 9d7d832eae66f8ace45dcc208501ba86689769fe Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 16 May 2026 17:44:18 -0400 Subject: [PATCH 1/2] solutions-engineering: tune lab bottleneck signals Make the CPU benchmark the obvious starting bottleneck, run both Docker platform builds on an x64 runner, and make the Dockerfile intentionally cache-unfriendly with native build work. Co-authored-by: Cursor --- .github/workflows/acme-ci.yml | 8 +-- .../migration-lab/Dockerfile | 8 +-- .../app/scripts/docker-build-workload.js | 68 +++++++++++++++++++ .../migration-lab/app/scripts/lint.js | 1 + 4 files changed, 76 insertions(+), 9 deletions(-) create mode 100644 solutions-engineering/migration-lab/app/scripts/docker-build-workload.js diff --git a/.github/workflows/acme-ci.yml b/.github/workflows/acme-ci.yml index b7c2b62..98c0e80 100644 --- a/.github/workflows/acme-ci.yml +++ b/.github/workflows/acme-ci.yml @@ -35,7 +35,7 @@ jobs: fraud-model-benchmark: name: Fraud model benchmark - runs-on: ubuntu-latest + runs-on: ubuntu-latest-4-cores steps: - uses: actions/checkout@v4 @@ -49,7 +49,7 @@ jobs: - run: npm run profile:cpu env: PROFILE_CPU_TASKS: 256 - PROFILE_CPU_ITERATIONS: 6250000 + PROFILE_CPU_ITERATIONS: 9500000 PROFILE_CPU_WORKERS: 32 unit-tests: @@ -105,10 +105,10 @@ jobs: include: - platform: linux/amd64 tag-suffix: linux-amd64 - runner: ubuntu-latest + runner: ubuntu-latest-4-cores - platform: linux/arm64 tag-suffix: linux-arm64 - runner: ubuntu-24.04-arm + runner: ubuntu-latest-4-cores steps: - uses: actions/checkout@v4 diff --git a/solutions-engineering/migration-lab/Dockerfile b/solutions-engineering/migration-lab/Dockerfile index c8ab911..a77eb77 100644 --- a/solutions-engineering/migration-lab/Dockerfile +++ b/solutions-engineering/migration-lab/Dockerfile @@ -1,12 +1,10 @@ -FROM --platform=linux/amd64 node:22-bookworm-slim +FROM node:22-bookworm-slim WORKDIR /app -COPY app/package*.json ./ +COPY app ./ RUN npm ci --omit=dev - -COPY app/src ./src -COPY app/scripts ./scripts +RUN node scripts/docker-build-workload.js EXPOSE 3000 diff --git a/solutions-engineering/migration-lab/app/scripts/docker-build-workload.js b/solutions-engineering/migration-lab/app/scripts/docker-build-workload.js new file mode 100644 index 0000000..a1c370a --- /dev/null +++ b/solutions-engineering/migration-lab/app/scripts/docker-build-workload.js @@ -0,0 +1,68 @@ +const crypto = require('crypto'); +const { Worker, isMainThread, parentPort, workerData } = require('worker_threads'); + +function taskCount() { + return Number(process.env.DOCKER_BUILD_TASKS || 64); +} + +function iterationCount() { + return Number(process.env.DOCKER_BUILD_ITERATIONS || 18000000); +} + +function workerCount() { + return Number(process.env.DOCKER_BUILD_WORKERS || 4); +} + +function runNativeBuildTask(iterations) { + const output = crypto.pbkdf2Sync( + 'acme-payments-container-build', + 'native-addon-build-cache', + iterations, + 64, + 'sha512', + ); + + return output.readUInt32BE(0); +} + +if (!isMainThread) { + parentPort.postMessage(runNativeBuildTask(workerData.iterations)); + return; +} + +function runTask(iterations) { + return new Promise((resolve, reject) => { + const worker = new Worker(__filename, { workerData: { iterations } }); + worker.once('message', resolve); + worker.once('error', reject); + worker.once('exit', (code) => { + if (code !== 0) { + reject(new Error(`worker exited with code ${code}`)); + } + }); + }); +} + +async function main() { + const tasks = taskCount(); + const iterations = iterationCount(); + const workers = Math.min(workerCount(), tasks); + let nextTask = 0; + + console.log(`running native build workload with tasks=${tasks} iterations_per_task=${iterations} workers=${workers}`); + + async function runQueue() { + while (nextTask < tasks) { + nextTask += 1; + await runTask(iterations); + } + } + + await Promise.all(Array.from({ length: workers }, () => runQueue())); + console.log('native build workload completed'); +} + +main().catch((error) => { + console.error(error.stack || error.message); + process.exit(1); +}); diff --git a/solutions-engineering/migration-lab/app/scripts/lint.js b/solutions-engineering/migration-lab/app/scripts/lint.js index 410f40a..634f973 100644 --- a/solutions-engineering/migration-lab/app/scripts/lint.js +++ b/solutions-engineering/migration-lab/app/scripts/lint.js @@ -7,6 +7,7 @@ const files = [ path.join(__dirname, 'shard-tests.js'), path.join(__dirname, 'integration-db-stress.js'), path.join(__dirname, 'docker-arch-check.js'), + path.join(__dirname, 'docker-build-workload.js'), path.join(__dirname, 'resource-profile.js'), ]; From 853786f20fce9f0ffb83767031279a344a3e14a6 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 16 May 2026 17:52:30 -0400 Subject: [PATCH 2/2] solutions-engineering: expand Docker cache exercise Add stable system dependency work after the app copy so the bonus Dockerfile optimization has a clearer layer-ordering target. Co-authored-by: Cursor --- solutions-engineering/migration-lab/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/solutions-engineering/migration-lab/Dockerfile b/solutions-engineering/migration-lab/Dockerfile index a77eb77..cb4ca68 100644 --- a/solutions-engineering/migration-lab/Dockerfile +++ b/solutions-engineering/migration-lab/Dockerfile @@ -3,6 +3,7 @@ FROM node:22-bookworm-slim WORKDIR /app COPY app ./ +RUN apt-get update && apt-get install -y python3 make g++ && rm -rf /var/lib/apt/lists/* RUN npm ci --omit=dev RUN node scripts/docker-build-workload.js