Skip to content

Add Spring.allow_reloading_disabled opt-in#755

Merged
rafaelfranca merged 1 commit into
rails:mainfrom
Korri:Korri/allow-disabled-reloading
May 26, 2026
Merged

Add Spring.allow_reloading_disabled opt-in#755
rafaelfranca merged 1 commit into
rails:mainfrom
Korri:Korri/allow-disabled-reloading

Conversation

@Korri
Copy link
Copy Markdown
Contributor

@Korri Korri commented May 25, 2026

Adds Spring.allow_reloading_disabled as an opt-in. The default :ensure_reloading_is_enabled initializer is unchanged and is the right default. Rails apps almost universally depend on Rails.application.reloader.reload! between Spring serves to pick up edits (route redraw, I18n reload, to_prepare callbacks, etc..). Booting Spring with that disabled is wrong for those apps and the check correctly refuses.

why?

The opt-in is useful, when running test, for apps where every resource that would require a reloader (translations, routes, ...) are lazy-loaded inside the forked child, and thus not loaded in the Spring parent.

In such apps, running with config.enable_reloading saves quite a bit of time on every test run, particularly on very large apps, where the reloaders have to stat tens of thousands of files on every test run to figure out if reloading is required.

@Korri Korri force-pushed the Korri/allow-disabled-reloading branch 5 times, most recently from 9893aa3 to 926ee4f Compare May 25, 2026 19:09
By default Spring refuses to boot when `config.cache_classes = true`
(a.k.a. `config.enable_reloading = false`) via the
`:ensure_reloading_is_enabled` initializer, with the message "Spring
reloads, and therefore needs the application to have reloading
enabled."

That guard predates the recognition that Spring's reload mechanism is
mold-restart-on-file-change via its own watcher (loaded application
features + initializers + config paths) — which works regardless of
whether Rails' in-process reloader is enabled. For projects that want
to disable Rails' reloader (e.g. to shed the per-serve
`reloaders.any?(&:updated?)` stat() pass over thousands of watched
files in large monorepos), the guard is unnecessarily strict.

This commit adds `Spring.allow_reloading_disabled` as an explicit
opt-in. Default remains `false` (the existing strict check). When set
to `true` the initializer is not registered and Spring boots normally
with reloading disabled.

The docstring on `Spring.allow_reloading_disabled` spells out what the
user gives up:

  1. Rails' `app.reloader.reload!` becomes a no-op. Anything that
     depends on it won't fire between Spring serves.

  2. With Zeitwerk + reloading disabled, autoloaded constants are
     non-reloadable. Tests that rely on the reloader resetting class
     state between runs may break.

  3. The user is responsible for asserting that lazy resources (routes,
     I18n, view paths) stay unmaterialized in the Spring mold so that
     each fork loads them fresh.

Acceptance test added covering the new opt-in.

Co-authored-by: AI (Pi/Claude Opus 4.7) <noreply@pi.dev>
@Korri Korri force-pushed the Korri/allow-disabled-reloading branch from 926ee4f to 84d5c98 Compare May 25, 2026 19:10
@Korri Korri marked this pull request as ready for review May 25, 2026 19:11
@Korri Korri force-pushed the Korri/allow-disabled-reloading branch from a02e823 to 84d5c98 Compare May 26, 2026 15:35
@rafaelfranca rafaelfranca merged commit 2ce1228 into rails:main May 26, 2026
56 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.

2 participants