Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Racing Inside ActiveSupport::Dependencies

#495

I'm working on a project that uses mongrel handlers to service requests. We use ActiveRecord but not ActionController. We've been seeing weird errors which look like:

#<LoadError: Expected ./my_model.rb to define MyModel>

the file does define the class but an exception is thrown. After some digging we found that the problem is in dependencies.rb in the require_or_load method.

If a thread is interrupted right after:

loaded << expanded

then any other threads that attempt to load the same file will get the error above, because the file hasn't been loaded yet even though it's name already appears in the loaded list.

I've included a test to reproduce this. The test only works against the development version of rails. If you want you can run it against other version but you will need to change the way Dependencies module is declared since it didn't used to be inside the ActiveSupport module.

I'm working on a patch right now, but any suggestions on how to fix this issue are more then welcome.

One last thing. When running the test please don't forget to change the first require to point at the correct location for activerecord.

Reported by skibumsworld · June 27th, 2008 @ 02:11 AM

State: stale
Milestone: 2.1.3
Assigned to: Jeremy Kemper Jeremy Kemper
Importance: High

Activity

  1. skibumsworld
    skibumsworld

    Same test, modified to run with activesupport 2.0.2

    June 27th, 2008 @ 03:43 AM

  2. Jeremy Kemper
    Jeremy Kemper
    • State changed from new to open
    • Milestone set to 2.1.1
    • Assigned user set to Jeremy Kemper

    June 27th, 2008 @ 08:53 AM

  3. DrMark
    DrMark

    Jeremy,

    While you are working in there, would you fix the typo in will_unload?. It is currently:

    def will_unload?(const_desc)

    autoloaded?(desc) ||

    explicitly_unloadable_constants.include?(to_constant_name(const_desc))

    end

    but should be:

    def will_unload?(const_desc)

    autoloaded?(const_desc) ||

    explicitly_unloadable_constants.include?(to_constant_name(const_desc))

    end

    Note the autoloaded line. I will make a separate ticket if necessary.

    Thanks!

    DrMark

    June 27th, 2008 @ 09:07 AM

  4. skibumsworld
    skibumsworld

    Here's a patch that fixes the problem.

    June 27th, 2008 @ 07:29 PM

  5. Jeremy Kemper
    Jeremy Kemper
    • Tag changed from activesupport, dependencies to activesupport, dependencies, patch

    skibumsworld, could you use a Mutex instead? Thread.critical has issues on jruby so other synchronization primitives are preferred.

    June 28th, 2008 @ 01:15 AM

  6. Jeremy Kemper
    Jeremy Kemper

    DrMark, will_unload? appears to be completely unused. Do you use it?

    June 28th, 2008 @ 01:16 AM

  7. DrMark
    DrMark

    Hi Jeremy,

    Yes. The benchmarkforrails plugin uses it (among others). I thought that it was odd that a bug that obvious could get through :)

    If you could fix it or remove it that would be great. That would save me having to monkey patch it all the time :)

    Thanks!

    June 28th, 2008 @ 03:52 AM

  8. Jeremy Kemper
    Jeremy Kemper

    Quite so, DrMark. I fixed it in master, 2-1-stable, and 2-0-stable. How odd.

    June 28th, 2008 @ 05:09 AM

  9. Jeremy Kemper
    Jeremy Kemper
    • Assigned user changed from Jeremy Kemper to josh
    • State changed from open to stale
    • Milestone cleared.

    July 30th, 2008 @ 10:06 AM

  10. Jeremy Kemper
    Jeremy Kemper
    • Milestone set to 2.1.3
    • State changed from stale to open
    • Assigned user changed from josh to Jeremy Kemper

    October 24th, 2008 @ 03:19 AM

  11. Stephen Bannasch
    Stephen Bannasch

    Here are links to two related bugs in ruby's implementation of require when used with threads:

    require is not thread-safe http://redmine.ruby-lang.org/iss...

    autoload is not thread-safe http://redmine.ruby-lang.org/iss...

    Basically there does not appear to be a safe way for require to work in a multi-threaded application unless the first use of require locks until the require is complete.

    December 27th, 2008 @ 04:23 PM

  12. Pratik
    Pratik
    • State changed from open to stale

    Putting the ticket in stale. Please reopen if this is still an issue.

    Thanks.

    March 8th, 2009 @ 02:07 PM