Skip to content

Get the test suite passing with Rails.application.ractorize! - #548

Closed
mhenrixon wants to merge 2 commits into
ankane:ractorizefrom
mhenrixon:ractorize-test-suite
Closed

mhenrixon wants to merge 2 commits into
ankane:ractorizefrom
mhenrixon:ractorize-test-suite

Conversation

@mhenrixon

@mhenrixon mhenrixon commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up to #547: this gets the test suite passing on your ractorize branch. RACTORIZE=1 rake test gives 191 runs, 0 failures on Ruby 4.0.7, Rails main (c41236f) and Rack main. The plain run is unchanged (191/0 on both the default Gemfile and activerecord82.gemfile).

Everything is test-only and behind RACTORIZE:

  • The error you saw: Ractor.make_shareable(Rails.application) reached the plain logger's Monitor through env_config["action_dispatch.logger"]. The fix is to use ActiveSupport::Ractors::Logger, as config.logger too.
  • unshareable_proc_action = :warn: Rails only makes the procs defined during boot shareable when this is set; Shopify's Ractor template sets :raise. Without it, message_verifiers' block still has the app as self. It's :warn rather than :raise because Combustion's to_prepare block captures an unfrozen options hash.
  • PgHero::Engine.instance.env_config before boot: the mounted engine is frozen when the routes are made shareable, but Rails::Engine#env_config only memoizes on the first request (Engine routes added with routes.append/routes.prepend keep the app from being ractorized rails/rails#59152).
  • consider_all_requests_local = false: the debug routing-error page memoizes into route nodes, which are frozen. That turned test_database_missing's 404 into a 500.
  • Skipping reload_routes_unless_loaded: test and development use LazyRouteSet, which calls it on every request. ractorize! drops the routes reloader and freezes the app, so every request raised FrozenError.

The last three are Rails issues with ractorize! outside production. The requests still run on the main Ractor; serving pghero's pages from a non-main Ractor would be the next step.

Conformance case

test/test_helper.rb:63: the whole suite, run after Rails.application.ractorize!

RACTORIZE=1 BUNDLE_GEMFILE=gemfiles/activerecord82.gemfile bundle exec rake test
  • Without the fix (96380f5, the ractorize branch), Ruby 4.0.7, Rails main c41236f, Rack main a9833c8: boot fails with Ractor::Error: can not make shareable object for #<Monitor:...> in Rails::Application#ractorize!.
  • With this PR: 191 runs, 0 failures on Ruby 4.0.7 (same Rails and Rack).

Run in CI, this catches anything pghero adds that ractorize! can't make shareable: a route proc, an unfrozen config value, a logger. The requests still run on the main Ractor, so it doesn't yet prove a page renders inside one. (Bundle with RACTORIZE=1 set, since that adds the Rack git source.)

@mhenrixon

Copy link
Copy Markdown
Contributor Author

Try this @ankane, that should work!

@ankane

ankane commented Oct 22, 2026

Copy link
Copy Markdown
Owner

Awesome, thanks @mhenrixon. Merged in the commit above.

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.

2 participants