Skip to content

fix: support auto-build with parallel tests - #630

Draft
ElMassimo wants to merge 1 commit into
mainfrom
parallel-tests
Draft

ElMassimo wants to merge 1 commit into
mainfrom
parallel-tests

Conversation

@ElMassimo

Copy link
Copy Markdown
Owner

GitHub Issue #376

Description 📖

This pull request makes autoBuild reliable when tests run in parallel processes.

Test workers can continue building assets on demand without requiring a separate precompilation step or runner-specific configuration.

Background 📜

Vite Ruby previously used a Mutex to serialize automatic builds. A mutex only coordinates threads within one Ruby process, while parallel test workers each have their own mutex.

When multiple workers requested stale assets together, they could launch concurrent Vite builds against the same output directory. A worker could then parse a manifest while another build was rewriting it, resulting in intermittent JSON::ParserError and ViteRuby::MissingEntrypointError failures.

This did not affect single-process test runs, and the existing mutex protected threaded requests within one process.

The Fix 🔨

Coordinate build checks and manifest reads through a project-scoped advisory file lock.

An exclusive lock covers the freshness check, Vite invocation, and metadata write. Waiting workers re-check freshness after acquiring the lock and reuse the first worker's build.

A shared lock prevents manifest reads from overlapping an automatic build. When autoBuild is disabled, manifest loading retains its previous behavior and does not initialize the builder or build lock.

MatheusRich added a commit to MatheusRich/vite_ruby that referenced this pull request Sep 24, 2026
The runner starts Vite through the package manager, for example
`bun x --bun vite`. When the vite package is not installed, Bun and
pnpm look for `vite` on the PATH. There they find the `vite`
executable of this gem, which starts the runner again. Each process
waits for its child, so the processes accumulate without end.

This commit adds a marker variable to the environment of the process
that the runner starts. When `vite build` or `vite dev` sees the
marker, it stops with an error. The error tells the user to install
the JavaScript packages. vite-plugin-ruby removes the marker when Vite
loads, so a process that Vite starts can still run `bin/vite`.

The check runs before `Builder#build`. With the build lock of PR ElMassimo#630,
a later check would deadlock instead of failing. The marker has no
`VITE_` prefix, because Vite copies those variables into
`import.meta.env`.

A check for `node_modules/.bin/vite` is not possible, because Yarn
Plug'n'Play has no `node_modules`. A check of the parent PID does not
work either, because pnpm starts the child through two processes.

With an older vite-plugin-ruby, `vite build` and `vite dev` fail when
a process that Vite started runs them. `DEFAULT_PLUGIN_VERSION` should
move to the next plugin release to prevent this.

This branch has not been deployed

No deployments
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.

1 participant