muirbot
muirbot

Reputation: 2081

Why does Rails not refresh classes on every request (despite configuration)?

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.

Upvotes: 14

Views: 4814

Answers (5)

E.E.33
E.E.33

Reputation: 2011

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

Upvotes: 7

muirbot
muirbot

Reputation: 2081

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.

Upvotes: 11

WattsInABox
WattsInABox

Reputation: 4636

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.

Upvotes: 2

Claw
Claw

Reputation: 767

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

Upvotes: 5

Dominik Grabiec
Dominik Grabiec

Reputation: 10665

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.

Upvotes: 0

Related Questions