-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
Zeitwerk not loading application_controller after a change in child controller. #38382
Comments
I created a new app with a filter like that and does not present this behavior, do you have a way to reproduce that you can share? Linking this to #38365, I suspect your project has something suspicious that manifests in reloading, but I'd bet the autoloader is not the root cause, since the problems reported happen in extremely common use cases. |
Could you please put puts caller in line 1 of |
Please find attached file as requested. Note that after |
Is that the entire log? The first occurrence of "ApplicationController" is
but the log does not show it was autoloaded before, nor does it show a |
I have done another trace, this time includes starting the server and the first successful page load, followed by a change to the child controller and then a reload. I cleared the terminal window at the start and then copied all into this file. The first three lines of
|
I also noticed in the
|
Let's follow that hint. That means the application is autoloading constants during initialization. Could you revise |
I found some constants in one of my initializers and commented them out, restarted server, but this did not fix the issue. However, the deprecation warning is still there. There is an issue concerning the deprecation warning. |
I experienced this and traced it down to a long-stale gem using bisection on the Gemfile. |
Interesting. Do you happen to remember the name of the culprit gem? And just to be clear, are you referring to the problem that the ApplicationController is not being reloaded or the deprecation warning. |
In my case it was http_status_exceptions. |
I'm referring to the deprecation warning. |
I will work on removing the deprecation warning and then see if that fixes the loading of the |
I have eliminated the deprecation warning by removing
The sequence of events traced in the attached file are
|
Hey, back to this one. First, let me say that class hierarchies are routinely reloaded. I bet there is something in that The line numbers of the relevant traces in the log file you attached are:
Autoloads are set, files are loaded, then unloaded, then new autoloads are defined, and we see one reload. But we are missing a trace for the second load of The key observations are the following:
Let me recall, just in case, that in Ruby a partial class definition is OK with the semantics of the language. Let's consider this example, begin
class C
raise
def foo; end
end
rescue
end
p C That runs without problem. It defines a class Could you please verify my conclusions and see if you can understand why the evaluation is partial? Once the exact source of the issue is understood, we will be able to think about whether there's anything to improve in Zeitwerk or Rails. |
Thank you for investigating this further. Looking in my ApplicationController and my ApplicationHelper, most of the code is straightforwardly procedural e.g. retrieving and massaging data from the database. The only method that does anything 'fancy' is this method, which is in the ApplicationHelper:
Do you think that could be causing the problem? I have tried sprinkling Do you have any suggestions how to use |
So, if you put puts 'TGM - Calling caller'
puts caller
class ApplicationController < ActionController::Base
puts "GOTCHA!"
# ...
end the second time you see "TGM", you don't see "GOTCHA!"? |
It is strange, but that is correct. |
OK, that is a hint. What does
print? |
The short answer is
If I stop spring, and issue the command again, I get a much longer trace, ending in the same place, with the immediately preceeding line is |
Let's follow that lead, if you disable Spring
does the issue happen? |
Yes, it still happens. And just to be sure, I ran the rails runner command after stopping the server and there was no mention of Spring and the full trace is printed out. |
OK, could you edit
add several traces in the |
The railstie code became:
and the output of
|
That does not seem to square at first sight. When did the reload happen? There was only one reload? Can you share the full log doing only one reload? |
Ah, and where's the "calling" trace? |
Can you inspect |
Here is the result of one succesful reload. |
Things that catch my attention:
|
|
Yes! The idea would be to identify the exact line in which execution mysteriously halts. So from
at the top, add "TGM #{klass} 1", "TGM #{klass} 2", "TGM #{klass} 3", ..., or something like that that allow us to say: there, something weird is going on in line N because we see "2" but not "3". You see the idea. |
Here is the railties code with put statements throughout
The |
Yes, We need one trace more, to see if we enter in
We are close! |
Excellent. Here is the same sequence with that line instrumented. It does look like it enters the if statement. Looking at that line reminds me that this is a very old app (rails 2 onwards) and I think it might be somewhere configured to allow all helpers to be accessible from all controllers. |
Can you wrap that line in a begin
klass.helper :all
rescue Exception => e
puts e.full_message
raise
end |
Here it is. temp_zeitwerks_3.txt |
Cool! So we have two things here. The more urgent one is that you know where's the problem. Would be cool to make sure also that
passes. The command is Please let me know if you manage to fix it and can work normally. Then, I'll try to understand how is it possible that the exception is silenced. |
Ok, will work on it tomorrow (it is evening here in Australia). Thanks for your help, and hope you are keeping safe in these strange times. |
Likewise! That was a good hunting session :), good night! |
I have now fixed it. I had quite a few namespaced helpers, so after the second one caused the same problem, I ended up moving them all into the main helpers directory, using the pattern that |
This should not be necessary, helpers can be namespaced. If it is necessary in your app, there's something to be understood. I'll see if I can reproduce any of this with |
Here is the output from rails zeitwerk:check
|
Precisely I am tonight trying to reproduce by including all helpers, and failing miserabily. The fix for that error you found (it is a bug in the Rake task itself) is going to ship with 6.0.3, there's a RC1 out. If you'd like to give it a try, depend on rails |
|
Excellent @obromios, so it passes the checks 👍. I have failed to reproduce. Namespaces working for eager loaded helpers, deliberate errors in helpers not silenced, reloads reloading without issues... I'd love to understand what happened in your app before the renames, but without a way to reproduce, it is hard. I believe the best action is to close then. But please let's reopen if anything shows up again. |
Steps to reproduce
Upgrade from
5.2
to rails6.0.2
. Have app working with all the new_frame_work_defaults removed. This issue was first raised as a SO question, but there have been no answers.Expected behavior
After making a change to controller and reloading a page belonging to that controller, it is expected that the web page should reload.
Actual behavior
In my application controller I define a filter called
set_locale
which I use in a number of child controllers. For example;Then in another controller I have
This arrangement works in rails 5, and works in rails 6 in the
test
andproduction
environments. Indevelopment
mode, the code works until I make a change to the code in theclubs_controller
. When I reload the page, I see the following exception:If I add
Rails.autoloaders.log!
toconfig/application.rb
, then when I start up the server, I see the following two entriesand then
as expected. But when I make a change and reload the page, I see
then later
which looks hopeful, but then finally
i.e no sign of the
ApplicationController
being reloaded.If I restart the server, then it runs properly again.
If I remove
config.load_defaults '6.0'
from my application.rb then everything works fine, but I am not seeing any output from autoloaders.log, so Zeitwerk is being disabled. This is a bit puzzling, if Zeitwerk is the default loader in Rails 6, why do I need to use config.load_defaults 6.0?System configuration
Rails version: 6.0.2
Ruby version: 2.6.5
The text was updated successfully, but these errors were encountered: