SPL Meter 0.4.3: a failed capture-tool build must not park the listener forever #31

Merged
michael merged 1 commits from claude/spl-build-retry into main 2026-09-28 11:31:51 -04:00
Owner

The SPL lane's copy of the deadlock found live in Timers and fixed there in 1.5.1 (#30), which flagged this file as the same latent pattern. In start(), if (missing !== BUILDING) skipped the retry while a build was in flight, and ensureCaptureBinary's onReady only fires on build success — so a failed build left the listener waiting forever on a callback that never comes ("Building the capture tool…" indefinitely), and a binary scp'd in from outside (the required path on AB, whose CLT cannot compile spl-capture) was never picked up without a module remount.

Same fix as #30: onReady stays as the fast path (successful build → immediate start), and the 30-second retry now stays armed in every not-ready state, so a failed build keeps re-checking and an externally supplied binary is found within half a minute.

Reproduced the production shape both ways with a swiftc that fails like AB's CLT: pre-fix, the build fails at 0 s, the binary is copied in at 3 s, and at 38 s it has never been spawned; post-fix, the 30 s retry spawns it (the binary's own "no input device matches" answer proves the real spawn path ran). spl-capture --selftest is unchanged against the IEC 61672 table (worst A error 3.14 dB @ 16 kHz/48 kHz, 0.59 dB @ 96 kHz — the documented bilinear-warping numbers).

Module 0.4.2 → 0.4.3, no shell changes. Stacked on #18 (0.4.2, the code running on AB and NA), so this PR's base is claude/spl-devices-without-binary: merge #18 first and then retarget this one to main by hand before merging it — Gitea does not retarget stacked PRs on its own here. Not deployed to AB or NA.

🤖 Generated with Claude Code

The SPL lane's copy of the deadlock found live in Timers and fixed there in 1.5.1 (#30), which flagged this file as the same latent pattern. In `start()`, `if (missing !== BUILDING)` skipped the retry while a build was in flight, and `ensureCaptureBinary`'s `onReady` only fires on build **success** — so a failed build left the listener waiting forever on a callback that never comes ("Building the capture tool…" indefinitely), and a binary scp'd in from outside (the required path on AB, whose CLT cannot compile spl-capture) was never picked up without a module remount. Same fix as #30: `onReady` stays as the fast path (successful build → immediate start), and the 30-second retry now stays armed in **every** not-ready state, so a failed build keeps re-checking and an externally supplied binary is found within half a minute. Reproduced the production shape both ways with a swiftc that fails like AB's CLT: pre-fix, the build fails at 0 s, the binary is copied in at 3 s, and at 38 s it has never been spawned; post-fix, the 30 s retry spawns it (the binary's own "no input device matches" answer proves the real spawn path ran). `spl-capture --selftest` is unchanged against the IEC 61672 table (worst A error 3.14 dB @ 16 kHz/48 kHz, 0.59 dB @ 96 kHz — the documented bilinear-warping numbers). Module 0.4.2 → 0.4.3, no shell changes. **Stacked on #18** (0.4.2, the code running on AB and NA), so this PR's base is `claude/spl-devices-without-binary`: merge #18 first and then retarget this one to `main` by hand before merging it — Gitea does not retarget stacked PRs on its own here. Not deployed to AB or NA. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
michael changed target branch from claude/spl-devices-without-binary to main 2026-09-28 11:31:29 -04:00
michael added 1 commit 2026-09-28 11:31:29 -04:00
Same deadlock the Timers module hit live on AB (fixed there in 1.5.1):
start() skipped scheduling its retry while a build was in flight, and
ensureCaptureBinary's onReady only fires on build SUCCESS. A failed
build therefore left the listener waiting forever on a callback that
never comes — "Building the capture tool…" indefinitely — and a binary
scp'd in from outside (the required path on AB, whose CLT cannot
compile) was never picked up without a module remount.

onReady stays as the fast path; the 30-second retry is now armed in
every not-ready state, so a failed build keeps re-checking and an
externally supplied binary is found within half a minute.

Reproduced pre-fix (build fails at 0s, binary copied in at 3s, still
untouched at 38s) and verified post-fix (retry at 30s spawns it).
spl-capture --selftest unchanged against the IEC 61672 table.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
michael merged commit 92b98b6579 into main 2026-09-28 11:31:51 -04:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: michael/ProdDash#31