Skip to content

Commit ff38608

Browse files
committed
docs(skills): record CAS hardware, fetcher count, log API cap, build timing
- ci-reference: add AX102-U CAS server specs (1Gbit/s, NVMe Gen4) and fetcher count reasoning (32 per job justified by hardware) - ci-reference: correct log API cap from ~23K to ~11K lines; note GHA UI as the only way to see live progress monitor output mid-build - buildstream: document why warm-cache builds still take 90-120 min (pull volume, two parallel variants, sequential OCI assembly, cold elements) - buildstream: document 32 fetchers as correct for AX102-U CAS - workflow-map: update paths-ignore entries to include files/scripts/** Assisted-by: Claude Sonnet 4.6 via GitHub Copilot
1 parent c46f9ea commit ff38608

3 files changed

Lines changed: 39 additions & 8 deletions

File tree

docs/skills/buildstream.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,18 @@ BST option names only allow alphanumeric characters and underscores. A name like
133133
### Weak-key caching can hide new packages behind a clean build (2026-06-07)
134134

135135
Changing a `kind: stack` dependency does not always invalidate downstream `compose` outputs in non-strict mode. If a package is present in the graph but missing from the final image, inspect cache behavior before assuming the package element is wrong.
136+
137+
### Warm-cache builds still take 90-120 min — this is normal (2026-06-23)
138+
139+
Even with a fully warm remote CAS, a full build takes 90-120 min. Common misconception: "cache is hot = fast build." Actual breakdown:
140+
141+
- **Pull volume:** ~1,400 elements × a few seconds each / 32 parallel fetchers = 15-30 min just for network pulls
142+
- **Two parallel jobs:** `default` and `nvidia` both run simultaneously, each hitting the same CAS endpoint, halving effective bandwidth per job
143+
- **OCI assembly is sequential:** After all elements pull/build, `oci/bluefin.bst` runs chunkify + image assembly — single-threaded, typically 20-40 min on its own
144+
- **Cold elements:** Any junction ref bump (Renovate PRs for distrobox, gnome-build-meta, etc.) invalidates those subtrees → full recompile from source adds 30-90 min
145+
146+
Do not cancel a build under 120 min just because it "seems slow." Historical range for successful builds: 90-150 min.
147+
148+
### 32 fetchers is the right setting for cache.projectbluefin.io (2026-06-23)
149+
150+
`buildstream-ci.conf` uses `fetchers: 32` (BST default is 10). With default + nvidia running simultaneously = 64 concurrent gRPC streams. The CAS server is a Hetzner AX102-U (1 Gbit/s uplink, NVMe Gen4) and can serve 64 streams comfortably. The bottleneck is network bandwidth (~125 MB/s total), not server capacity. Do not reduce fetchers without evidence of server-side saturation.

docs/skills/ci-reference.md

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ Route through `ci.md` first, then come here only when the focused skills do not
8383

8484
`cache.projectbluefin.io:11002` handles all five BST remote services: artifact cache, source cache, CAS storage, remote execution, and action cache. All use the same endpoint with mTLS auth.
8585

86+
**CAS server hardware (Hetzner AX102-U):**
87+
- CPU: AMD Ryzen 9 7950X3D (16c/32t, 4.2 GHz base)
88+
- RAM: 128 GB DDR5
89+
- Storage: 2 × 1.92 TB NVMe SSD Gen4
90+
- Network: 1 Gbit/s dedicated uplink (unlimited traffic)
91+
92+
**Fetcher count reasoning:** `buildstream-ci.conf` uses `fetchers: 32` per job. With default + nvidia running simultaneously = 64 concurrent gRPC streams. The AX102-U can comfortably serve 64 streams; the actual ceiling is the 1 Gbit/s uplink (~125 MB/s total). 32 fetchers per job is appropriate. Do not lower without evidence of CAS-side saturation.
93+
8694
### mTLS Authentication
8795

8896
| Variable | Type | Content |
@@ -578,7 +586,7 @@ for job in d.get('jobs', []):
578586
print(f\"{job['id']} | {job['status']} | {mins}m | {job['name'][:60]}\")
579587
"
580588
581-
# 2. Fetch the live log (note: truncated at ~23K lines for long builds)
589+
# 2. Fetch the live log (note: truncated at ~11K lines = first 2-5 min of dense BST output)
582590
gh api repos/projectbluefin/dakota/actions/jobs/<job-id>/logs > /tmp/bst-live.log
583591
584592
# 3. Count cache hits vs elements being compiled
@@ -589,11 +597,19 @@ grep "Running commands" /tmp/bst-live.log | tail -20 # what's actively building
589597
grep "START.*Running commands" /tmp/bst-live.log | grep -oE "\[.*\]" | sort -u
590598
```
591599

592-
**Important:** The live log endpoint is a snapshot, not a stream. For builds
593-
running > ~90 minutes, the log may be stale by 60–90 minutes relative to current
594-
wall-clock time. If the last log timestamp is behind by > 1 hour, the build is
595-
still running but log data is not being returned. Use `gh api
596-
repos/.../actions/runs/<id>/jobs` to confirm `status: in_progress`.
600+
**Important:** The live log endpoint is a snapshot, not a stream. The API caps at
601+
**~11K lines** which covers only the first 2-5 minutes of dense BST output — for a
602+
2-hour build you see essentially nothing useful after the first few minutes. This
603+
is a GitHub API limitation, not a BST issue.
604+
605+
**To see progress monitor output mid-build:** Open the GHA UI directly:
606+
`https://github.com/projectbluefin/dakota/actions/runs/<run-id>` — the
607+
`bst-progress.py` monitor emits lines every 30 seconds in the live log stream
608+
viewable in browser. The API endpoint does NOT stream these.
609+
610+
For builds running > ~90 minutes, the API log timestamp will be far behind
611+
wall-clock. Use `gh api repos/.../actions/runs/<id>/jobs` to confirm
612+
`status: in_progress`.
597613

598614
**Deciding whether to re-trigger:** A build making steady progress on
599615
gnome-build-meta `core-deps/` elements is normal cache-warming after a GNOME

docs/skills/workflow-map.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ push: testing/main (BST paths) / Tuesday 04:00 UTC / manual ← PARALLEL, DECO
7878

7979
| Workflow | Owns | Normal trigger |
8080
|---|---|---|
81-
| `.github/workflows/build.yml` | BST build into remote CAS | `push: main/next/testing` (paths-ignore: docs, workflows, md), `merge_group`, `workflow_dispatch`. `validate` job runs on `pull_request` only; `build` job skips `pull_request`. |
82-
| `.github/workflows/build-aarch64.yml` | aarch64 OCI build + GHCR push | `push: main/testing` (same paths-ignore as build.yml), `schedule: Tuesday 04:00 UTC`, `workflow_dispatch`. Fully decoupled — never in `needs:` of publish/promote/release. |
81+
| `.github/workflows/build.yml` | BST build into remote CAS | `push: main/next/testing` (paths-ignore: docs, workflows, md, `files/scripts/**`), `merge_group`, `workflow_dispatch`. `validate` job runs on `pull_request` only; `build` job skips `pull_request`. |
82+
| `.github/workflows/build-aarch64.yml` | aarch64 OCI build + GHCR push | `push: main/testing` (same paths-ignore as build.yml including `files/scripts/**`), `schedule: Tuesday 04:00 UTC`, `workflow_dispatch`. Fully decoupled — never in `needs:` of publish/promote/release. |
8383
| `.github/workflows/publish.yml` | export, sign, boot-check, promote tags | `workflow_run` from build |
8484
| `.github/workflows/publish-smoke.yml` | observational smoke only | `workflow_run` from publish |
8585
| `.github/workflows/e2e.yml` | PR-facing testsuite check | `pull_request` |

0 commit comments

Comments
 (0)