Why does Rails not refresh classes on every reques

2019-01-26 05:33发布

问题:

I recently started having to restart my development server every time I change my code. My development.rb file still has this line:

config.cache_classes = false

I tried using the debugger verify that this value has stuck around. To do this I set my configuration to a global variable in environment.rb:

$my_initializer = Rails::Initializer.run do |config|
  ...
end

then I put a debugger line in one of my controllers so I could do this:

(rdb:2) $my_initializer.configuration.cache_classes
false

So that eliminated the possibility that the value of cache_classes was getting set to true somewhere else. I've tried using both Mongrel and WEBrick and it still happens.

What else might be causing Rails not to reload my code with every request?

I am running: Mongrel 1.1.5
WEBrick 1.3.1
Rails 2.3.8
Ruby 1.8.7 p253

EDIT: at @Daemin 's suggestion I checked that the mtime of my files are are actually getting updated when I save them in my text editor (Textmate)

merced:controllers lance$ ls -l people_controller.rb 
-rwxr-xr-x  1 lance  staff  2153 Act 10 18:01 people_controller.rb

Then I made a change and saved the file:

merced:controllers lance$ ls -l people_controller.rb 
-rwxr-xr-x@ 1 lance  staff  2163 Oct 11 12:03 people_controller.rb

So it's not a problem with the mtimes.

回答1:

If anyone else has this problem the solution was the order: config.threadsafe! has to come before config.cache_classes. Reorder it like this to fix it:

...
config.threadsafe!
config.cache_classes = false
...

answer from: Rails: cache_classes => false still caches



回答2:

So it turns out that config.threadsafe! overwrites the effect of config.cache_classes = false, even though it doesn't actually overwrite the value of cache_classes (see my question for proof). Digging around a bit more in the Rails source code might illuminate why this might be, but I don't actually need threadsafe behavior in my development environment. Instead, I replaced my call to config.threadsafe! in environment.rb to

config.threadsafe! unless RAILS_ENV == "development"

and everything works fine now.



回答3:

I suspect that the classes you are expecting to refresh have been 'required' somewhere in your configuration. Note that Rails' dependency loading happens after Ruby's requires have happened. If a particular module or class has already been required, it will not be handled by Rails' dependency loader, and thus it will not be reloaded. For a detailed explanation, check out this article: http://spacevatican.org/2008/9/28/required-or-not



回答4:

Despite the fact that the threadsafe! solution works, I also wanted to point out for your benefit and the others that may come in after the following...

If you're editing engine code that is directly in your vendor/engines directory, those files will not be updated without a restart. There may be a configuration option to enable such functionality. However, this is very important to remember if you have used engines to separate large bits of functionality from your application.



回答5:

My guess would be that it's not reloading the classes for each request because they haven't changed between requests. So the system would note down the last modified time when the classes are loaded, and not reload them until that changed.