How is Actionpack is not thread-safe? @@allow_concurrency?


#1

Hi,

I found many references on the Web to the fact
that “Rails is not thread-safe”.

However, I have not found an explanation why it isn’t?

What happens if multiple requests are handled concurrently
by ActionPack?

Assuming that the code I execute in my controller methods
is thread safe, is this ok?

If not – what happens?

The following makes it sound like the issue is
whether the app is thread-safe:

# Controls whether the application is thread-safe, so multi-threaded 

servers like WEBrick know whether to apply a mutex
# around the performance of each action. Action Pack and Active
Record are by default thread-safe, but many applications
# may not be. Turned off by default.
@@allow_concurrency = false
cattr_accessor :allow_concurrency

@@allow_concurrency is apparently only used in caching.rb,
which makes sense…

Anyway - I am working on an app that needs to preserve state
from request to request, so I can’t have multiple processes
to allow for concurrency; it has to be done within
one ruby process using threads.

If there is a problem, I’m willing to put some time and effort
into fixing this, so I would appreciate any pointers.

Right now I don’t really see what the problem is.

Thanks,

-Rick


#2

Hi !

On May 12, 2006, at 8:05 AM, Rick wrote:

Assuming that the code I execute in my controller methods
# around the performance of each action. Action Pack and Active
to allow for concurrency; it has to be done within
one ruby process using threads.

If there is a problem, I’m willing to put some time and effort
into fixing this, so I would appreciate any pointers.

Right now I don’t really see what the problem is.

Thanks,

-Rick

I'm not sure of the exact repercussions of why rails is not thread

safe. But you are going to run into trouble trying to have one rails
process and keeping state in threads between requests. This is not
going to work for you. What you really need to do instead is either
use the session to store state between requests. Or even better run a
drb(distributed ruby) server that holds the state you need between
requests. This way you can have as many fcgi’s or rails processes as
you want and they all get and put their state into the drb server on
each requests. THis makes for a nice seperation of concerns when you
need to maintain state like you want to.

But can you give an example of what you mean by keeping state

between requests? What are you trying to accomplish exactly? Details
would help me give you a better suggestion and maybe even some code.

-Ezra


#3

On May 12, 2006, at 8:05 AM, Rick wrote:

I found many references on the Web to the fact that “Rails is not
thread-safe”.

[…]

If there is a problem, I’m willing to put some time and effort into
fixing this, so I would appreciate any pointers.

Depending upon what needs to be locked this may introduce significant
pessimisations to Rails. Adding locking can be very expensive even
if your locks are fine-grained enough. It would be better for you to
find a different way of solving your problem.


Eric H. - removed_email_address@domain.invalid - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com


#4

My app needs to look at about 20% of the total data
for every request.

The total amount of data I have is about 2MB. Writing this
data to a relational database would require about 30 tables.
Lots of unnecessary code, conversion, and room for errors.

It seems silly to read and write so much data to/from the database
for every request. Much more straightforward to keep it
all in memory. It’s only 2MB!!!

So what exactly is the problem?

It seems like the process is as follows:

  1. Request comes in, Rails does stuff, then calles my controller
  2. I do stuff in my controller
  3. Rails renders the view and sends the data. This will again call some
    of my code.

Where in (1) or (3) is the problem, and what does Rails do that
isn’t thread safe?

Or is it that Ruby is not not robust enough with multiple threads?

Please let me know.

Thanks…

Ezra Z. wrote:

Hi !

On May 12, 2006, at 8:05 AM, Rick wrote:

Assuming that the code I execute in my controller methods
# around the performance of each action. Action Pack and Active
to allow for concurrency; it has to be done within
one ruby process using threads.

If there is a problem, I’m willing to put some time and effort
into fixing this, so I would appreciate any pointers.

Right now I don’t really see what the problem is.

Thanks,

-Rick

I’m not sure of the exact repercussions of why rails is not thread
safe. But you are going to run into trouble trying to have one rails
process and keeping state in threads between requests. This is not
going to work for you. What you really need to do instead is either
use the session to store state between requests. Or even better run a
drb(distributed ruby) server that holds the state you need between
requests. This way you can have as many fcgi’s or rails processes as
you want and they all get and put their state into the drb server on
each requests. THis makes for a nice seperation of concerns when you
need to maintain state like you want to.

But can you give an example of what you mean by keeping state
between requests? What are you trying to accomplish exactly? Details
would help me give you a better suggestion and maybe even some code.

-Ezra


#5

this is no error but by design…

I know from fastcgi, that for every concurrent request you need one
process instance of the fcgi-handler. rails can serve as much concurrent
requests as number of process instances are available.

keeping data in instance variables between requests will just not
work!

you should consider using memory-based tables, or even better,
memcached.

http://www.danga.com/memcached/

cheers
Peter

-------- Original-Nachricht --------
Betreff: [Rails] Re: How is Actionpack is not thread-safe?
@@allow_concurrenc
Datum: Sat, 13 May 2006 12:25:25 +0200
Von: Rick B. removed_email_address@domain.invalid
An: removed_email_address@domain.invalid


#6

Peter E. wrote:

this is no error but by design…

What’s the point of @@allow_concurrency, then?

keeping data in instance variables between requests will just not
work!

Why not? It works fine on my dev machine, there are provisions
for setting rails up so that no new interpreter is started for every
request,
there is @allow_concurrency, etc.

And no one has been able to give me one example or reason why
it doesn’t work.

you should consider using memory-based tables, or even better,
memcached.

Thanks for the pointer. But my point is – why should I flatten
everything into a relation model when I can store everything
in memory…