15

It seems to me that the Ruby community has been freaking out a little about autoload since this famous thread, discouraging its use for thread safety reasons.

Does anyone know if this is no longer an issue in Ruby 1.9.1 or 1.9.2? I've seen a bit of talk about wrapping requires in mutexes and such, but the 1.9 changelogs (or at least as much as I've been able to find) don't seem to address this particular question. I'd like to know if I can reasonably start autoloading in 1.9-only libraries without any reasonable grief.

Thanks in advance for any insights.

Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
SFEley
  • 7,660
  • 5
  • 28
  • 31

3 Answers3

9

Bringing a 2011 update to this, since I was curious about it too.

Two tickets are currently opened:

The core devs suggest that require and autoload work in the same manner and are thread safe, in CRuby/JRuby 1.9. This, in the sense that ruby keeps a lock until the file is fully loaded.

This has the inconvenient side-effect of introducing potential deadlocks, however. Specifically:

  1. Th1 load A and locks it
  2. Th2 load B and locks it
  3. Th1 tries to load B as part of loading A, starts waiting for Th2
  4. Th2 tries to load A as part of loading B, starts waiting for Th1
  5. Deadlock...

The conclusion probably is: require everything you need before starting a thread if there's any potential for deadlock in your app.

Denis de Bernardy
  • 75,850
  • 13
  • 131
  • 154
  • 1
    I can imagine this kind of thing happening on a threaded server whose initial page loads trigger tons of autoloading. The above two threads actually has a mention of this very scenario. – Denis de Bernardy Jul 02 '11 at 13:20
  • 2
    Adding to this, it's worth noting that irrespective of ruby thread safety, [event-machine isn't thread-safe](https://github.com/eventmachine/eventmachine/issues/97). Considering that both thin and goliath are based on it, and that neither of mongrel nor webrick use threads, and that mod_rack relies on mongrel/webrick workers, it doesn't really matter at the end of the day. ;-) – Denis de Bernardy Jul 02 '11 at 13:24
  • 1
    Digging deeper into this. Partially ignore my last comment. Mongrel actually allows to use threads (but rails was not thread safe when it did). And mod_rack actually *exposes* Rack methods - it uses neither of mongrel/webrick, it uses forks which share (some) memory between processes. – Denis de Bernardy Jul 03 '11 at 20:24
7

I don't know about the general case, but repro example from that thread doesn't break in 1.9.1:

autoloaded.rb:

sleep 1
Bar::Foo = 1

autoloader.rb:

module Bar
   autoload :Foo, 'autoloaded.rb'
end

t1 = Thread.new { Bar::Foo }
t2 = Thread.new { Bar::Foo }
t1.join; t2.join
  • 2
    D'oh. Why oh why didn't I think of that? After reproducing it myself and trying some stress-test variations (and confirming with RVM that it IS still broken in 1.8.7, JRuby, and Rubinius -- everything **except** 1.9.1 and 1.9.2) I'm calling this answered. Thank you! – SFEley May 15 '10 at 17:11
  • I'm surprised that it isn't thread-safe in JRuby - I thought that thread-safety was one of their aims. – Andrew Grimm May 16 '10 at 23:08
-4

it's always broken.

subload allows you to switch modes when in a threaded environment.

I use autoload still in threaded environment, but only during a single threaded boot sequence. I don't see any good reason to have a multithreaded startup process in a real world application. If you do have one, you will likely need to queue up actions for loading shared libraries as you will always have thread safety issues with class and instance level setup, most partuclarly with things like:

class Lib
  extend SomeClassFuncs
  do_something_with_class_funcs
end

This code is not thread safe a load time, irrespective of the loader.

If you can't see this, you shouldn't be threading.

raggi
  • 1,290
  • 9
  • 12
  • Subload? What's subload? --I do see your point, but as you point out, that sort of metaprogramming is just as thread-unsafe with `require` as with `autoload`. My question was whether the specific bug in `autoload` that was documented by Charles Nutter some time ago had been fixed in Ruby 1.9, and it has been. – SFEley Jun 15 '10 at 15:58
  • The autoload thread safety bug cannot be fixed. Only some cases can be adjusted. – raggi Mar 06 '11 at 10:58
  • subload was a library that competed with the autoload feature and offered a behavior akin to the rails eager load facility that came later. It's no longer relevant, but was in some use at the time. – raggi Mar 29 '21 at 03:38