Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><strong>In short:</strong></p> <ol> <li>No, Rails <em>never</em> runs in a shared-nothing environment.</li> <li>Be paranoid about <em>class variables</em> and <em>class instance variables</em>.</li> </ol> <p><strong>The longer version:</strong></p> <p>Rails processes start their life cycle by loading the framework and application. They will typically run only a single thread, which will process many requests during its lifetime. The requests will therefore be dispatched strictly <em>sequentially</em>.</p> <p>Nevertheless, all classes persist across requests. This means any object referenced from your classes and metaclasses (such as class variables and class instance variables) <em>will</em> be shared across requests. <strong>This may bite you</strong>, for example, if you try to memoize methods (<code>@var ||= expensive_calculation</code>) in your <em>class</em> methods, expecting it will only persist during the current request. In reality, the calculation will only be performed on the first request.</p> <p>On the surface, it may seem nice to implement caching, or other behaviour that depends on persistence across requests. Typically, it isn't. This is because most deployment strategies will use <em>several</em> Rails processes to counter their own single-threaded nature. It is simply not cool to block all requests while waiting for a slow database query, so the easy way out is to spawn more processes. Naturally, these processes do not share anything (except some memory perhaps, which you won't notice). <strong>This may bite you</strong> if you save stuff in your class variables or class instance variables <em>during requests</em>. Then, somehow, sometimes the stuff appears to be present, and sometimes it appears to be gone. (In reality, of course, the data may or may not be present in some <em>process</em>, and absent in others).</p> <p>Some deployment configurations (most notably JRuby + Glassfish) <em>are</em> in fact multithreaded. Rails is thread safe, so it can deal with it. But your application may not be thread safe. All controller instances are thrown away after each request, but as we know, the classes are shared. <strong>This may bite you</strong> if you pass information around in class variables or in class instance variables. If you do not properly use synchronisation methods, you may very well end up in race condition hell.</p> <hr> <p>As a side note: Rails is typically run in single-threaded processes because Ruby's thread implementation sucks ass. Luckily, things are a little better in Ruby 1.9. And a <em>lot</em> better in JRuby.</p> <p>With both these Ruby implementations gaining in popularity, it seems likely that multithreaded Rails deployment strategies will also gain in popularity and number. It is a good idea to write your application with multithreaded request dispatching in mind already.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload