Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revise how to disable eager loading app/channels #513

Closed
wants to merge 1 commit into from
Closed

Revise how to disable eager loading app/channels #513

wants to merge 1 commit into from

Conversation

fxn
Copy link
Contributor

@fxn fxn commented Nov 11, 2023

Background

If the parent application does not use Action Cable, turbo-rails prevents app/channels from being eager loaded, since some necessary classes do not exist.

The root issue

The interface of config.eager_load_paths and friends has always been ill-defined.

For example, config.autoload_paths is empty, while config.eager_load_paths is not. This is confusing, don't you think? In any case, only pushing to these collections was documented, and pushing ended up doing what it was expected, unless you also used the paths API, in which case you'd hit a long-standing bug that was fixed in Rails 7.1.2.

Bottom line, deletion from those collections was not something you could rely on. It worked on this collection by pure chance, and would have no effect in others. This interface did not exist, basically. And the fix in Rails 7.1.2 not only revises the logic, but also clarifies the contract for these collections.

The patch

In order to be able to not eager load app/channels, we leave that deletion for classic because it works and that won't change in old releases. But for applications loading with Zeitwerk, we use the interface that is documented to work.

Note that Rails.autoloaders.zeitwerk_enabled? still exists today, even if Zeitwerk has been the only autoloader since Rails 7. And it does so precisely for cases like this in which engines need to support multiple Rails versions.

Testing

Unfortunately, there are no tests for this. I only tried manually. Being able to test this would need work in the test harness of turbo-rails itself. There is more conditional code in the initializers to be tested. You'd need different dummy apps, and for this particular case, test/test_helper.rb should not assume the ActionCable constant is defined, or should be refactored somehow.

But that is out of the scope of this PR. This patch fixes the issue to be able to ship a new version of turbo-rails, and I'll leave work on an improved test harness to the Hotwire team.

Fixes #512.

seanpdoyle added a commit to seanpdoyle/turbo-rails that referenced this pull request Nov 11, 2023
Follow-up to [hotwired#513][]

Rely on [on_load hooks][] to extend test helpers. Despite the fact that
Action Cable is an optional dependency and Action Dispatch is not, this
commit replaces all `class`-style extensions with `on_load` hooks for
the sake of consistency.

There isn't a hook for `ActionCable::Channel::TestCase`, so waiting for
`action_cable_channel` to fire is the best that we can do.

[hotwired#513]: hotwired#513
[on_load hooks]: https://guides.rubyonrails.org/engines.html#available-load-hooks
@seanpdoyle
Copy link
Contributor

There is more conditional code in the initializers to be tested. You'd need different dummy apps, and for this particular case, test/test_helper.rb should not assume the ActionCable constant is defined, or should be refactored somehow.

But that is out of the scope of this PR.

@fxn I've opened up #514. Does that achieve what you're describing?

@fxn
Copy link
Contributor Author

fxn commented Nov 11, 2023

@seanpdoyle in principle that might work.

However, what is really needed is a proof that an application that does not have Action Cable loaded does not eager load app/cache. And CI would test that for Rails 7 and Rails 6, say.

Same for the branch guarded by Rails.application.config.respond_to?(:assets).

Without knowing more about the project, I'd refactor that test_helper.rb depending on whether that eases writing those missing tests or not.

@ghiculescu
Copy link
Contributor

Is this okay to merge? Otherwise I think it will break tests for any new Rails app that doesn't use Action Cable.

@fxn fxn closed this by deleting the head repository Jan 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Can't load turbo-rails without Action Cable starting in Rails 7.1.2
3 participants