From 6e777e687580ef542c758d6b8d1aedc05d58d031 Mon Sep 17 00:00:00 2001 From: Paul Keen <125715+pftg@users.noreply.github.com> Date: Tue, 25 Aug 2026 21:41:52 +0200 Subject: [PATCH] ci: the MRI retry budget went stale the same way JRuby's did `3.3/rails81` timed out on run 32889000873 and cancelled nine sibling cells with it. Tests were still printing dots when SIGTERM landed -- slow, not hung, the same signature as the JRuby timeout #289 fixed a release earlier. #289 left the MRI number alone on the grounds that "MRI is 128s against 3 min and does not move". That was true when written. Measured now on run 32770212615, the last green master run: 3.4/rails81 78s 4.0/rails72 89s 3.4/rails80 123s 4.0/rails80 131s 3.4/rails71 132s 3.4/rails72 134s 3.3/rails81 144s <- against a 180s cap, and the cell that timed out 4.0/edge 146s 23% headroom at the slowest, down from the ~40% the 3-minute figure was chosen for. 4 minutes puts it back to ~64%, and the job cap follows so the arithmetic stays true: 1 + 4 + 4 = 9. The comment now says the general thing outright, because this is twice: these numbers are MEASUREMENTS, not settings. A suite that grows silently erodes every budget derived from it, and the failure mode is a cell that has been passing by seconds until the day it does not. Costs nothing on a green run -- it is a ceiling, not a sleep. YAML validated. --- .github/workflows/test.yml | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0e5ecf04..838c4c10 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -143,8 +143,8 @@ jobs: runs-on: ubuntu-latest # Must fit `max_attempts * timeout_minutes` below, plus ~1 min of setup, # or the last attempt gets killed mid-run and the cell reports `cancelled` - # -- a dead gate. JRuby: 1 + 20 + 20 = 41. MRI: 1 + 3 + 3 = 7, under 8. - timeout-minutes: ${{ contains(matrix.ruby-version, 'jruby') && 41 || 8 }} + # -- a dead gate. JRuby: 1 + 20 + 20 = 41. MRI: 1 + 4 + 4 = 9. + timeout-minutes: ${{ contains(matrix.ruby-version, 'jruby') && 41 || 9 }} continue-on-error: ${{ matrix.experimental }} strategy: matrix: @@ -212,11 +212,20 @@ jobs: # so it was slow, not hung. # # 20 min restores ~26% over the slowest attempt, which is the margin - # this was originally sized for. MRI is 128s against 3 min and does - # not move. If JRuby ever exceeds this again, re-measure and raise - # BOTH numbers -- a per-attempt timeout that does not fit the job cap - # reports `cancelled`, which reads as an absence rather than a fail. - timeout_minutes: ${{ contains(matrix.ruby-version, 'jruby') && 20 || 3 }} + # this was originally sized for. + # + # MRI then did the same thing one release later, which is why it is 4 + # and not 3. "MRI is 128s against 3 min" was true when written; measured + # on run 32770212615 the attempts are 78-146s, so the slowest had 23% + # left and `3.3/rails81` (144s) duly timed out on run 32889000873 -- + # again with tests still printing dots when SIGTERM landed. 4 min puts + # the slowest back to ~64%. + # + # The lesson both times: these numbers are measurements, not settings. + # When one bites, RE-MEASURE and raise BOTH it and the job cap -- a + # per-attempt timeout that does not fit the cap reports `cancelled`, + # which reads as an absence rather than a failure. + timeout_minutes: ${{ contains(matrix.ruby-version, 'jruby') && 20 || 4 }} # Two, not three. A third attempt never fit inside the job cap on # either engine (JRuby 3x15=45 > 25; MRI 3x3=9 > 8), so it only ever # got killed partway and reported the cell as `cancelled`. Keeping