Repository navigation
Fix the Rails 7.1 unrestorable busy wait test - #81
Merged
Merged
Conversation
The unrestorable busy wait test assumed that its connection already had a Ruby busy handler, which PRAGMA busy_timeout reads as 0. Rails 7.2 and later install that handler on each new connection, and an earlier sync call installs it too. A new Rails 7.1 connection instead uses SQLite's own busy_timeout, which PRAGMA reads as 5000. When the test ran first on Rails 7.1, the adapter correctly took the restorable path and put back SQLite's own wait. That wait holds the Ruby VM lock, so the releaser thread could not release the write lock, and the write raised SQLite3::BusyException after 5 s. Seed 11785 failed every time; CI run 35874660739 failed the same way. Install the handler in the test and assert that PRAGMA reads 0, so the test checks the unrestorable path on every Rails version and order.
|
No job had a time limit. In run 36888691442, apt-get update inside "npx playwright install --with-deps chromium" stopped after its fifth index download and printed nothing for 6 hours, until GitHub cancelled the javascript job at its 360-minute default. The same step on the same commit took about 3 minutes in the pull_request run. Give every job a 15-minute limit, as solid-objects-js does. In the last 25 successful runs, the longest job took 491 s, so the limit leaves room for a slow runner and stops a hang in 15 minutes instead of 6 hours.
cardmagic
added a commit
that referenced
this pull request
Oct 3, 2026
…bility Bring in the Rails 7.1 busy wait test fix and the CI job timeout from #81.
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.
Summary
test_sync_leaves_an_unrestorable_busy_wait_alonefailed on Rails 7.1 when it ran before any other test had touched its connection. CI run 35874660739 failed this way, and seed 11785 fails every time onmain.The test checks that a sync call leaves alone a busy wait that the adapter cannot read back. It stubs
configured_busy_handler_timeouttonil, so the adapter readsPRAGMA busy_timeout. The test assumed that its connection already had a Ruby busy handler, whichPRAGMA busy_timeoutreads as 0:PRAGMA busy_timeoutbusy_handler_timeout=On a new Rails 7.1 connection, the adapter correctly took the restorable path and put back SQLite's own wait. That wait does not release the Ruby VM lock, so the releaser thread in
write_while_write_lock_is_briefly_heldcould not release the write lock. The write raisedSQLite3::BusyExceptionafter the full 5 s.The test now installs the Ruby busy handler on its connection and asserts that
PRAGMA busy_timeoutreads 0. It checks the unrestorable path on every Rails version and in every test order. Only the test changes; the adapter behaved correctly.CI job time limits
The first push run of this PR (36888691442) did not fail a test. Its
javascriptjob hung innpx playwright install --with-deps chromium:apt-get updateprinted its fifth index download at 16:01 and then nothing, until GitHub cancelled the job at its 360-minute default at 22:01. The same step on the same commit took about 3 minutes in the pull_request run. Over the last 60 runs, this step took a median of 25 s.445cf27 gives every job
timeout-minutes: 15, assolid-objects-jsdoes. In the last 25 successful runs, the longest job (javascript) took 491 s. A hang now fails in 15 minutes instead of 6 hours.actionlintpasses.Compatibility
Test and CI configuration only. No runtime, API, or migration effect. Not applicable to
solid-objects-js, which has no Rails connection or Ruby VM lock.Validation
ActiveRecord::StatementInvalid: SQLite3::BusyException: database is lockedatwrite_while_write_lock_is_briefly_heldafter about 6 s.bundle exec rake test TESTOPTS="--seed=11785": 797 runs, 1 error (this test,BusyException).return nil unless pragma_timeout.positive?fromSqlite#restorable_busy_waitmakes the adapter overwrite the handler. The changed test then fails withSQLite3::BusyExceptionon Rails 7.1.6 and 8.1.3.1.bundle exec rake: 797 runs, 2,707 assertions, 0 failures/errors, 28 skips. Standard, RuboCop, RBS validation, Steep, and Brakeman passed.Rails 7.1 runs used
RAILS_VERSION=7.1 bundle lock --update --local, as the CI compatibility job does.