This project is archived and is in readonly mode.
models are not loaded in migrations when config.threadsafe! is set
Reported by Andrew Roth | April 16th, 2009 @ 04:14 AM | in 2.x
- Make a new rails project
- Make a new model, and refer to the model somewhere in the migration
- Enable config.threadsafe! in production mode, and migrate in production mode
ex ruby script/generate resource Test
class CreateTests < ActiveRecord::Migration
def self.up
Test
create_table :tests do |t|
t.timestamps
end
end
def self.down
drop_table :tests
end
end
and config/environments/production.rb has
# Enable threaded mode
config.threadsafe!
rake db:migrate RAILS_ENV=production produces
(in /Users/andrewroth/Development/test_models_in_migration)
== CreateTests: migrating ====================================================
rake aborted!
An error has occurred, this and all later migrations canceled:
uninitialized constant CreateTests::Test
(See full trace by running task with --trace)
without threadsafe! it loads Test correctly.
Comments and changes to this ticket
-
calavera May 28th, 2009 @ 05:00 PM
the threadsafe option in production doesn't load the dependencies, you can configure it to load them with this option in your production.rb just after config.threadsafe!
config.dependency_loading = true
but I don't know how rails can behave with both options enabled in production
-
thedarkone May 29th, 2009 @ 09:19 AM
I'm pretty sure
config.threadsafe!
auto-requires all*.rb
files it can find in your app on start up. -
calavera May 29th, 2009 @ 09:42 AM
@thedarkone take a look at the threadsafe! source code:
# Enable threaded mode. Allows concurrent requests to controller actions and # multiple database connections. Also disables automatic dependency loading # after boot, and disables reloading code on every request, as these are # fundamentally incompatible with thread safety. def threadsafe! self.preload_frameworks = true self.cache_classes = true self.dependency_loading = false self.action_controller.allow_concurrency = true self end
with dependency_loading = false rails doesn't autoload dependencies and models are a dependency of migrations
-
thedarkone May 30th, 2009 @ 04:48 PM
Automatic dependency loading is not thread safe, that's why it is being disabled.
Also checkout what happens in
load_application_classes
method ifcache_classes
is set totrue
. -
Pratik May 30th, 2009 @ 05:38 PM
- Assigned user set to josh
-
josh June 9th, 2009 @ 03:07 PM
- State changed from new to wontfix
I don't think there is a good fix here. The real issue is that turning off dependency_loading doesn't allow "magic" loading after boot. I would suggest requiring the models the you need in the migration, or better including the model definition again so the migration doesn't depend on its existence.
-
Reto July 27th, 2009 @ 01:30 PM
- Tag changed from 2.3.2, migrations to 2.3.4, migrations
Could we add a warning about that problem somewhere near the config in environments/production.rb? Or perhaps even in the actual 'const missing' error message? 'This might be caused by the fact that you running your application in threadsafe! mode. Please require all dependencies explictily.
I could set up a proposel version on github, if you guys would support one of these measures.
-
Andrew Roth July 28th, 2009 @ 08:19 PM
Wouldn't that break lots of existing migrations?
What about making threadsafe! not be applied when doing migrations? Even if it's set in the config file. It really only benefits long-running apps, no?
-
Reto July 28th, 2009 @ 08:19 PM
Or could we even force a non-threadsafe environment for rake tasks? It doesn't make sense to be threadsafe there anyway.
-
Reto July 28th, 2009 @ 08:30 PM
lol, what a coincidence :).
"Wouldn't that break lots of existing migrations": No, why? I would only extend the text message of the 'no such constant' exception, of course only when the threadsafe option has been set. And perhaps only the first time.
-
Andrew Roth July 28th, 2009 @ 09:42 PM
Regardless, you said yourself it at least doesn't make sense. But it would make every migration that accesses a model invalid for any application that uses threadsafe!
-
Reto July 29th, 2009 @ 10:30 AM
hmm, I think I can't follow you? What exactly would make these migrations invalid? If they used to avoid that problem by explicitly require models then they shouldn't notice the difference. Or what do you mean?
-
Andrew Roth August 18th, 2009 @ 03:45 AM
What I mean is that right now, people are writing migrations that access models. I've done it myself when using a legacy database to get a table name, ex. add_column Person.table_name, ... or maybe to repair some inconsistent data put in by a bug, like orphaned or duplicate rows.
What it comes down to is whether the solution is to make people require models in migrations, or make migration loading work in migrations (when threadsafe! is on). I would say that being able to access models in migration is reasonable, and being widely used right now, so the proper way to fix this is to make model accesses work in migrations. The simplest way I can think of to do that is to disable threadsafe mode when migrating somehow.
Of course, an explanation in the error message is better than nothing though.
-
Ryan Daigle October 21st, 2009 @ 04:35 PM
I'm experiencing this behavior with rake tasks as well. This would seem to be more problematic since there's no philosophical opposition to referencing models within rake tasks?
My specific scenario is that I have a rake bootstrap task that sets up some default system data. Even when depending on the :environment task to load everything up for me, my models aren't found within the rake task unless explicitly required. Disabling config.threadsafe! fixes the reference issues.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>