From a24600f1a7431efbdb185ccb4abcb7c303d04a90 Mon Sep 17 00:00:00 2001 From: goodboy Date: Wed, 13 May 2026 10:10:27 -0400 Subject: [PATCH] Add `main_thread_forkserver` CI matrix rows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add `capture` dimension to CI matrix so fork-based backends run `--capture=sys` (fork-child × `--capture=fd` is a known deadlock). Non-fork backends keep `fd`. Deats, - two `include:` rows for `main_thread_forkserver` on linux py3.13: tcp + uds, both `capture: 'sys'` - job name updated to show `capture=` mode - timeout bumped 16 -> 20 min to accommodate the additional matrix cells - `--capture=${{ matrix.capture }}` replaces hardcoded `--capture=fd` (this patch was generated in some part by [`claude-code`][claude-code-gh]) [claude-code-gh]: https://github.com/anthropics/claude-code --- .github/workflows/ci.yml | 48 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6eff3bcb..6eb6e69e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,10 +83,27 @@ jobs: testing: - name: '${{ matrix.os }} Python${{ matrix.python-version }} spawn_backend=${{ matrix.spawn_backend }} tpt_proto=${{ matrix.tpt_proto }}' - timeout-minutes: 16 + name: '${{ matrix.os }} Python${{ matrix.python-version }} spawn_backend=${{ matrix.spawn_backend }} tpt_proto=${{ matrix.tpt_proto }} capture=${{ matrix.capture }}' + timeout-minutes: 20 runs-on: ${{ matrix.os }} + # NOTE on the matrix shape — the `capture=` mode follows + # `spawn_backend`: + # + # - `trio` / `mp_*` backends use `--capture=fd` (default) + # for per-test attribution of subactor *raw-fd* output + # in failure reports. + # - Fork-based backends (`main_thread_forkserver`, + # `subint_forkserver`) REQUIRE `--capture=sys` because + # fork-child × `--capture=fd` is a known deadlock + # pattern. See the long NOTE in `tractor._testing.pytest`'s + # `pytest_load_initial_conftests` for the mechanism + + # tradeoff write-up. + # + # If a future matrix row adds a fork-spawn backend + # WITHOUT setting `capture: 'sys'`, the + # `pytest_load_initial_conftests` hook fail-fasts on `CI=1` + # with a clear error msg. So the matrix is self-policing. strategy: fail-fast: false matrix: @@ -113,6 +130,26 @@ jobs: 'tcp', 'uds', ] + capture: [ + 'fd', # default for non-fork backends + ] + + # Fork-based backends — added via `include:` so each + # cell carries its REQUIRED `capture: 'sys'` mode. + # Linux-only for now; macOS coverage TBD pending + # local validation. + include: + - os: ubuntu-latest + python-version: '3.13' + spawn_backend: 'main_thread_forkserver' + tpt_proto: 'tcp' + capture: 'sys' + - os: ubuntu-latest + python-version: '3.13' + spawn_backend: 'main_thread_forkserver' + tpt_proto: 'uds' + capture: 'sys' + # https://github.com/orgs/community/discussions/26253#discussioncomment-3250989 exclude: # don't do UDS run on macOS (for now) @@ -153,8 +190,11 @@ jobs: -rsx --spawn-backend=${{ matrix.spawn_backend }} --tpt-proto=${{ matrix.tpt_proto }} - --capture=fd - # ^XXX^ can't work with --spawn-method=main_thread_forkserver + --capture=${{ matrix.capture }} + # NOTE: capture mode is matrix-driven — `fd` for + # non-fork backends (per-test fd attribution), + # `sys` for fork-based (avoids fork-child x + # capture-fd deadlock). See matrix-NOTE above. # XXX legacy NOTE XXX #