From 9efd61c0e6bcb12c620c1339074cf0e49d0d35be Mon Sep 17 00:00:00 2001 From: sotashimozono Date: Wed, 5 Aug 2026 00:06:02 +0000 Subject: [PATCH] feat(ci): a `cache` input, because a persistent depot pays for the cache twice (#62) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `julia-actions/cache@v3` ran in both jobs with no guard and no way to turn it off, while this workflow's own default runner is `'["self-hosted","rosina"]'` — a pool whose Julia depot already persists per box, and per runner since the depot-front change. There the restore is a no-op and the SAVE is not. MEASURED, from #62. One green eight-shard run (FunctionMeasures.jl 30826019824): 44–182 s of post-step per shard against 58–268 s of actual testing, ≈620 s of runner time per run for a depot that was already on the box. The single shared key makes it worse rather than better here — all N shards finish together and then all upload the same large depot, N−1 of them pointlessly even when they succeed. And when it does not merely cost, it hangs. Three jobs on 2026-08-03 whose `Run shard` step SUCCEEDED went red or never finished in that post-step, one holding a runner for 114 minutes. The failure shape is the bad one: tests pass, job red, and nothing in `gh pr checks` tells that apart from a real failure without opening the step list. A hung post-step also holds a self-hosted runner indefinitely, so it shrinks the pool for everyone and reads downstream as ordinary queueing. Seen again today on ParaLinearAlgebra.jl 30961107784: six shards on `rosina` spent 4–5 minutes EACH in the post-step and finished; the two on `panza` were still in it 16 minutes later with every test green. `cache` defaults to `true`, so a hosted caller is unaffected — it is the caller that knows whether its depot survives the job. The org-wide reusable, whose default runner is the self-hosted pool, sets it false in the companion PR. --- .github/workflows/sharded-tests.yml | 16 ++++++++++++++++ Project.toml | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/sharded-tests.yml b/.github/workflows/sharded-tests.yml index 285f7b8..39d53b3 100644 --- a/.github/workflows/sharded-tests.yml +++ b/.github/workflows/sharded-tests.yml @@ -102,6 +102,20 @@ on: description: 'Report what the timing history says about the shape of the suite.' type: boolean default: true + cache: + description: > + Cache the Julia depot between runs with `julia-actions/cache`. `true` is right for a + HOSTED runner, whose depot is gone at the end of the job. Set it FALSE on a pool whose + depot already persists: there the restore is a no-op and the SAVE is not. + + Measured on one green eight-shard run (FunctionMeasures.jl 30826019824): 44–182 s of + post-step per shard, ≈620 s of runner time per run, against 58–268 s of actual testing — + a cache costing about what the tests cost, for a depot that was already on the box. And + when it does not merely cost, it hangs: three jobs on 2026-08-03 whose test step + SUCCEEDED went red or never finished in that post-step, one of them holding a runner for + 114 minutes, which reads downstream as ordinary queueing. See #62. + type: boolean + default: true steal: description: > Claim work instead of being assigned it. Each shard runs whatever is still unclaimed, @@ -320,6 +334,7 @@ jobs: with: version: ${{ inputs.julia-version }} - uses: julia-actions/cache@v3 + if: ${{ inputs.cache }} with: cache-name: testshards include-matrix: 'false' @@ -442,6 +457,7 @@ jobs: with: version: ${{ inputs.julia-version }} - uses: julia-actions/cache@v3 + if: ${{ inputs.cache }} with: # ONE key for all shards. They instantiate the same project, so a per-shard key # would keep N separate depots and pay precompilation N times over — the dominant diff --git a/Project.toml b/Project.toml index 9e7e916..7a18157 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "TestShards" uuid = "acceef1d-f5e0-4fe4-a546-818dc56ce7b2" -version = "0.3.33" +version = "0.3.34" authors = ["sota shimozono "] [deps]