andy
andy

Reputation: 8875

In what way is Ruby on Rails NOT multithreaded?

Disclaimer: I'm a c# ASP.NET developer learning "RoR". Sorry if this question doesn't "get" RoR, any corrections greatly appreciated!

What is multithreading

My understanding of "multithread" ability in web apps is twofold:

  1. Every time a web/app server receives a request it can assign a thread to the new request, thus multiple requests can run concurrently.
  2. The app runtime + language allows for multiple threads to be used WITHIN a single request (in ASP.NET via "Async" methods and keywords for example).

In this way, IIS7 + ASP.NET can do points 1 AND 2.

I'm confused about RoR

I've read these two articles and they have left me confused:

question one.

I think I understand that RoR doesn't lend itself very well to point number 2 above, that is, having multiple threads within the same request, have I got that right?

question two.

Just to be crystal clear, RoR app/web servers can also do point number 1 above right (that is, multiple requests can run concurrently)? is that not always the case with RoR?

Upvotes: 29

Views: 24992

Answers (3)

kjw0188
kjw0188

Reputation: 3685

Question 1: You can spawn more Ruby threads in one request if you want, although that seems to be outside the typical use case for Rails. There are uses for it for certain long-running IO or external operations.

Question 2: The limiting factor for Ruby concurrency in general, not just with Rails, is the Global Interpreter Lock. This feature of Ruby prevents more than 1 thread of Ruby from executing at any given time per process. The lock is released whenever there is non-Ruby code executing, such as waiting for disk IO or SQL responses. You can get around this by using a different implementation of Ruby than the default, such as JRuby, but not all.

Phusion Passenger uses process based concurrency to handle a few requests concurrently, so, strictly speaking, is not "multithreaded," but is still concurrent.

This talk from Ruby MidWest 2011 has some good thoughts on getting multithreaded Ruby on Rails going.

Upvotes: 37

Amir Abiri
Amir Abiri

Reputation: 9417

Since this is about "from ASP.NET to RoR" there is another small but important detail to remember: In *nix environments it's common to achieve concurrency of a service application through multi-processing rather than multi-threading. This is an architecture that goes way back and is related to the relatively cheap cost of multi-processing on *nix systems using fork and Copy-on-Write. Each process serves one request at a time in a single thread and the main process controls spawning and killing worker child processes. Multiple requests are served concurrently by different child processes.

Modern service applications, for example Apache, have multi-process, multi-threaded, and even combined modes (where the service forks several processes, each running several threads).

In cases where the application was built with portability at mind (examples again: Apache, MySQL, etc) it is customary to run it in multi-process or combined mode on *nix systems, and in multi-threaded mode on Windows servers.

However, admittedly Rails is somewhat lacking on the Windows front. It's not that you can't run it on Windows, it's just that not a lot of effort went into making sure it runs well and smoothly for production use on Windows servers. It's not a common production platform among the RoR community.

As a result, Eventhough Rails itself is thread-safe since version 2.2, there isn't yet a good multi-threaded server for it on Windows servers. And you get the best results by running it on *nix servers using multi-process/single-threaded concurrency model.

Upvotes: 3

Vibhor Mahajan
Vibhor Mahajan

Reputation: 336

Rails as a framework is thread-safe. So, the answer is yes!

The second link that you posted here names many of the Rails servers that don't do well with multi-threading. He later mentions that nginx is the way to go (it is definitely the most popular one and highly recommended). But he doesn't mention what made him come up to the conclusions. Ruby 1.9.3 came out recently and has some new threading goodness built in which didn't exist before.

Use of multi-threading generally depends on the use case. Personally I have tried it once an year ago and it had worked but I haven't used it in any production code because I haven't come across a use case where using multi-threading made more sense over pushing the long running task to a background job.

I would love to explore this more. So, if you can describe what you are trying to achieve then maybe we can do a POC.

Upvotes: 2

Related Questions