Skip to content

perf(runner): drop five process forks per hooked test - #1355

Merged
Chemaclass merged 1 commit into
mainfrom
feat/1345-hook-temp-file-without-forks
Sep 9, 2026
Merged

perf(runner): drop five process forks per hooked test#1355
Chemaclass merged 1 commit into
mainfrom
feat/1345-hook-temp-file-without-forks

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Related #1345

A test in a file that defines set_up or tear_down cost 3.3x a hookless one. Each hook minted its output file with mktemp and removed it with rm, and the ownership marker that left behind made the runner rm -rf the test's temp files at exit — five forks per test, even for a test that created no temp file of its own.

💡 Changes

  • Name the hook output file arithmetically in the run directory instead of through bashunit::temp_file, keyed on the folded file path plus the per-suite ordinal so parallel workers cannot collide. The > redirect truncates, so nothing has to remove it.
  • Hooked tests now cost the same as hookless ones: 14.1ms → 5.4ms per test on macOS arm64, bash 3.2. This suite runs 1052 such tests.
  • Share the vanished-run-directory guard that discovery grew for The suites acceptance test is flaky on Bash 3.0 under load #1137, so a failed capture redirect cannot read as the hook itself failing.
  • Correct the fork-budget rule: its census fixture defines no hooks, which is why this never showed up.

https://claude.ai/code/session_01EXYWTGLjf7qM8Ru3GakDRm

A test in a file defining set_up or tear_down cost five process forks
more than a hookless one: each hook minted its output file through
bashunit::temp_file (mktemp) and removed it with rm -f, and the
temp-owner marker mktemp leaves behind made the EXIT trap rm -rf the
test's temp files even when the test created none. That is 14.1ms per
test against 5.4ms hookless here, and this suite runs 1052 such tests.

Name the file arithmetically in the run directory instead, the way
discovery.sh already names its source-error capture: the folded file
path (keeps two files sharing a basename apart, #959) plus the
per-suite ordinal the dispatcher assigns before forking (#851), since a
Bash 3 subshell inherits both $$ and the RANDOM state. The > redirect
truncates, so nothing has to remove it and the run-dir cleanup takes it
at the end. Hooked and hookless tests now cost the same.

Reusing the run dir also inherits its known hazard, so extract the
vanished-directory guard discovery.sh grew for #1137 and share it: a
failed redirect otherwise reads as the hook itself failing.

The census in perf-fork-budget.md called the per-test path fork-free.
It measured a fixture that defines no hooks, which is why this never
showed up; the rule now says so.

Closes #1345

Claude-Session: https://claude.ai/code/session_01EXYWTGLjf7qM8Ru3GakDRm
@Chemaclass Chemaclass added the enhancement New feature or request label Sep 9, 2026
@Chemaclass Chemaclass self-assigned this Sep 9, 2026
@Chemaclass
Chemaclass merged commit f9fbde9 into main Sep 9, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/1345-hook-temp-file-without-forks branch September 9, 2026 07:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant