Skip to content

improvement: re-check the subproject PLT outside mix check's parallel section - #246

Merged
jimsynz merged 2 commits into
mainfrom
fix/dsl-material-colour-typo
Aug 27, 2026
Merged

improvement: re-check the subproject PLT outside mix check's parallel section#246
jimsynz merged 2 commits into
mainfrom
fix/dsl-material-colour-typo

Conversation

@jimsynz

@jimsynz jimsynz commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Fixes #245 together with beam-bots/bb_example_wx200#97 and
beam-bots/bb_example_so101#91.

Root cause

Not the cache key, and not a stale PLT. mix gettext.extract --check-up-to-date
re-expands the gettext macros by force-recompiling the project
(mix compile --force-elixir + mix compile.elixir --force), and a forced
recompile empties _build/dev/lib/<app>/ebin and .../consolidated before
refilling them. Polled every 50 ms in bb_example_wx200, that window is about
two seconds:

40.86 ebin=21 consolidated=27
41.59 ebin=21 consolidated=0     <- consolidated/ emptied
41.70 ebin=1  consolidated=0     <- ebin emptied, .app file only
43.47 ebin=21 consolidated=0
43.76 ebin=21 consolidated=27

ex_check runs the gettext tool in parallel with dialyzer. Elixir's build
lock serialises the two compiles — that is what the "Waiting for lock on the
build directory" lines in the failing logs are — but not dialyzer's beam reads,
which happen after it releases the lock: first the PLT check, then the
Path.wildcard in Dialyxir.Project.dialyzer_files/0 that builds its file list.
A wipe landing across both gives exactly the reported failure: the PLT check
can't read a consolidated protocol beam, and the file list comes back empty.

Only bb_example_wx200 and bb_example_so101 carry both gettext and
dialyxir, which is why only those two jobs fail — bb_example_so101 failed
identically on the v0.30.1 tag push (run 32619948357), so it was never really
PR-only either. The issue's consolidate_protocols lead is a red herring: those
two are Phoenix apps and don't set it, so they do consolidate in :dev. Setting
it would remove one of the two error lines and leave the empty file list.

What this changes

The Force a PLT re-check step deleted _build/*/*.plt.hash and left the
re-check itself to mix check, where it runs alongside every other tool and
spends twenty-odd seconds reading every beam in the build directory. That is the
amplifier: with a valid hash, dialyzer's exposure is the ~0.15 s between
releasing the build lock and globing the ebin; with the hash deleted it is the
whole PLT check. This PR primes the PLT in that step instead, so the re-check
still happens — same correctness, same total work, moved out of the parallel
section.

That narrows the window; it doesn't close it. The two .check.exs PRs above
close it, by making the gettext tool depend on dialyzer so the forced
recompile runs when nothing else is reading _build. All three are needed.

The first commit is the real source touch used to make the downstream matrix
recompile bb (a one-character typo fix in the color entity's docs, plus the
regenerated cheat sheet). It's a genuine fix, so it stays rather than being
reverted.

Verification

Reproduced locally, byte for byte. In bb_example_wx200 with
BB_VERSION=local and _build/*/*.plt.hash deleted, overlapping
mix gettext.extract --check-up-to-date with mix dialyzer:

:dialyzer.run error: File not found:
  .../_build/dev/lib/bb_example_wx200/consolidated/Elixir.Collectable.beam
  files: [],
:dialyzer.run error: Analysis failed with error:
No .beam files to analyze (no --src specified?)
Halting VM with exit status 1

Same file, same empty files: [] as the CI logs. With the .check.exs fix,
mix check --no-retry moves the forced recompile to the last three seconds of
the run, after dialyzer has finished.

Not reproduced naturally in CI, and I can show why. The bb_example_wx200
and bb_example_so101 jobs pass on this PR — but they also pass on a scratch PR
carrying only the source touch with this workflow unchanged (#247, closed), so
that green is not evidence of a fix. Re-running the 23 Aug job that failed
(run 32674375855, job 97280389283) unchanged, today, also passes. The timings
against the same _build cache key have moved a long way since:

23 Aug (failed) today (passes)
ex_unit 0:13 0:49
dialyzer 0:21 1:51

gettext is gated on ex_unit, so it now starts around 50 s in, well clear of
dialyzer's PLT check. That is consistent with a timing race rather than anything
about the branch, and it means CI cannot currently demonstrate either the break
or the fix.

This PR's step does behave as intended (job 98350500869): the PLT check runs
in its own step for 81 s, and mix dialyzer inside mix check then drops from
0:21–0:36 to 0:16 with no PLT-check phase at all.

"meterial" -> "material", and regenerate the DSL cheat sheet.
@jimsynz
jimsynz marked this pull request as ready for review August 26, 2026 22:43
@jimsynz

jimsynz commented Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

reopening to kick off the workflows

@jimsynz jimsynz closed this Aug 26, 2026
@jimsynz jimsynz reopened this Aug 26, 2026
…el section

Deleting `_build/*/*.plt.hash` forces dialyxir to re-check the PLT against bb's
current source, but it left that check inside `mix check`, where it runs
alongside every other tool. The check spends twenty seconds or so reading beams
out of `_build/dev`, and a tool that recompiles the project during that window
empties the ebin and the consolidated protocol directory underneath it —
`bb_example_wx200` and `bb_example_so101` run `mix gettext.extract`, which
force-recompiles, and dialyzer halts with "No .beam files to analyze".

Priming the PLT in its own step shrinks dialyzer's exposure inside `mix check`
to the moment it globs the ebin, and moves the same work out of the parallel
section rather than adding any.
@jimsynz jimsynz changed the title fix: stop the downstream dialyzer step racing gettext in _build improvement: re-check the subproject PLT outside mix check's parallel section Aug 26, 2026
@jimsynz
jimsynz merged commit 6cc4ccc into main Aug 27, 2026
39 of 40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Test Subprojects: bb_example_wx200 dialyzer fails on every source-changing PR

1 participant