Почему Rails не обновляет классы по каждому запросу (несмотря на конфигурацию)?


Недавно мне пришлось перезапускать сервер разработки каждый раз, когда я меняю свой код. Мое развитие.в файле rb все еще есть эта строка:

config.cache_classes = false

Я попытался с помощью отладчика проверить, что это значение застряло. Для этого я установил свою конфигурацию в глобальную переменную в среде.РБ:

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

Затем я вставил строку debugger в один из своих контроллеров, чтобы я мог сделать это:

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

Таким образом, исключалась возможность того, что значение cache_classes устанавливалось в true в другом месте. Я пробовал использовать и Mongrel, и WEBrick, и это все еще происходит.

что еще может заставить Rails не перезагружать мой код с каждым запросом?

Я бегу.: Дворняга 1.1.5
WEBrick 1.3.1
Рельсы 2.3.8
Ruby 1.8.7 p253

Править: по предложению @Daemin я проверил, что mtime моих файлов на самом деле обновляется, когда я сохраняю их в своем текстовом редакторе (Textmate)

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

Затем я внес изменения и сохранил файл:

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

Так что это не проблема с mtimes.

5 14

5 ответов:

Если у кого-то еще есть эта проблема, то решение было таким: config.threadsafe! должно прийти раньше config.cache_classes. Переупорядочить его так, чтобы исправить это:

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

Ответ от: Rails: cache_classes = > false still caches

Таким образом, получается, что config.threadsafe! перезаписывает эффект config.cache_classes = false, хотя на самом деле он не перезаписывает значение cache_classes (см. мой вопрос для доказательства). Покопавшись немного больше в исходном коде Rails, можно понять, почему это может быть, но мне на самом деле не нужно threadsafe поведение в моей среде разработки. Вместо этого Я заменил свой вызов на config.threadsafe! в среде.rb to

config.threadsafe! unless RAILS_ENV == "development"

И все работает теперь нормально.

Я подозреваю, что классы, которые вы ожидаете обновить, были "обязательными" где-то в вашей конфигурации. Обратите внимание, что загрузка зависимостей Rails происходит после того, как произошли requireS Ruby. Если определенный модуль или класс уже был необходим, он не будет обработан загрузчиком зависимостей Rails и, следовательно, не будет перезагружен. Подробное объяснение можно найти в этой статье: http://spacevatican.org/2008/9/28/required-or-not

Несмотря на то, что threadsafe! решение работает, я также хотел бы отметить для вашей пользы и других, которые могут появиться после следующего...

Если вы редактируете код движка, который находится непосредственно в каталоге поставщика/движков, эти файлы не будут обновлены без перезагрузки. Для включения такой функциональности может существовать опция конфигурации. Тем не менее, это очень важно помнить, если вы использовали движки, чтобы отделить большие биты функциональности от вашего приложение.

Я бы предположил, что это не перезагрузка классов для каждого запроса, потому что они не изменились между запросами. Таким образом, система будет записывать последнее измененное время, когда загружаются классы, и не перезагружать их, пока это не изменится.