This project is archived and is in readonly mode.

#2506 ✓wontfix
Andrew Roth

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

    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

    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

    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

    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 if cache_classes is set to true.

  • Pratik

    Pratik May 30th, 2009 @ 05:38 PM

    • Assigned user set to “josh”
  • 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

    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

    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

    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.

  • Andrew Roth
  • Reto

    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

    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

    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

    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

    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>

Pages