test(hew-cli): serialize wasm stdlib archive builds under the shared bootstrap lock - #2874
Open
gertybotbot wants to merge 2 commits into
Open
test(hew-cli): serialize wasm stdlib archive builds under the shared bootstrap lock#2874gertybotbot wants to merge 2 commits into
gertybotbot wants to merge 2 commits into
Conversation
…bootstrap lock build_wasi_runtime_serialized takes a cross-process fd_lock before invoking cargo, with a doc comment explaining that parallel nextest processes otherwise each see the staticlib absent, each launch a build, and race Cargo's non-atomic staticlib write so wasm-ld reads a truncated or transiently-absent archive. build_wasi_stdlib_archive is called from the same bootstrap loop, builds the same kind of wasm32-wasip1 staticlib, and had the identical is_file() fast path with no lock at all. That leaves libhew_std.a exposed to exactly the race the sibling function documents -- consistent with hew-lang#1924, where the failure surfaces in the support harness rather than an assertion and is far more likely on the slower macOS runner. Hoist the lock into open_wasi_bootstrap_lock and take it in both builders, so all wasm32-wasip1 staticlib builds serialize on one lock file regardless of which artifact a given process found missing. Both keep their unlocked fast path, so the common all-artifacts-present case is unchanged. Refs hew-lang#1924
The CI 'Clippy & format' job covers rustfmt as well as clippy; the local check ran only clippy, so a hand-written over-long format! passed locally and failed CI. Reflow only, no logic change.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #1924.
The asymmetry
bootstrap_wasi_runnercalls two builders in sequence:The first takes a cross-process
fd_lockbefore invoking cargo, and its doc commentalready names the hazard precisely:
The second builds the same kind of wasm32-wasip1 staticlib, from the same loop, into
the same directory — and had the identical
is_file()fast path with no lock atall.
libhew_std.awas left exposed to exactly the race its sibling documents.hew-testutil'sensure_hew_lib_builtlocks too, so the unlocked stdlib builder wasthe only one of the three that didn't.
That matches #1924's signature: the failure surfaces in the support harness rather
than an assertion, appears on PRs that touch neither hew-cli nor wasm-eval, and is
far likelier on the slower macOS runner where the build window stays open longer.
The change
Hoist the lock into
open_wasi_bootstrap_lockand take it in both builders, so everywasm32-wasip1 staticlib build serializes on one lock file regardless of which artifact
a given process found missing. A per-builder lock would not do: the point is that
different builders contend with each other.
Both keep their unlocked fast path and their post-lock re-check, so the common
all-artifacts-present case (CI pre-build, or a sibling finished first) is unchanged.
Verification
Mutual exclusion is proven directly rather than assumed, with a control:
ENTER runtime / EXIT runtime / ENTER stdlib-hew-std / EXIT stdlib-hew-std / ENTER stdlib-2 / EXIT stdlib-2ENTER runtime / ENTER stdlib-hew-std / ENTER stdlib-2 / EXIT...Three processes on the real
fd_lock+ real lock filename. Locked: perfectly nested,no interleaving. Unlocked: all three inside the critical section at once — i.e. three
concurrent
cargo buildinvocations racing the same non-atomic staticlib write.cargo clippy -p hew-cli --tests→ RC=0 (captured bare, not through a pipe)cargo test -p hew-cli --test eval_e2e wasm→ 16 passed, 0 failed, RC=0,including
eval_wasm_file_runtime_failure_exits_with_child_exit_code, the testnamed in the issue.
What this does not claim
A flake fix cannot be proven by a green run — passing was always the common case. The
evidence here is structural: a documented race, a sibling that guards against it, an
unguarded third path, and a control showing the guard is what prevents concurrency.
If #1924 recurs after this, the remaining suspect is the warm-binary/settling issue
in the body's second hypothesis (cf. #1887), which this does not address.
Issue #1924 is left open deliberately — closing it needs runner evidence over time,
not a merge.