views:

121

answers:

2

I know Rails.cache is ActiveSupport::Cache::MemoryStore, and it is not thread safe.

I don't understand, why rails use a thread-unsafe cache as its default? Why not use ActiveSupport::Cache::SynchronizedMemoryStore? In my opinion, in a web site, if a cache is not thread-safe, it almost useless, because the requests are not handled in ONE thread.

Do you use Rails.cache in you webapp? And how do you use it?

+1  A: 

The default cache store in Rails is ActiveSupport::Cache::FileStore, not MemoryStore.

The memory store is of limited use in practice, since it is restricted to a single process, which makes it useless for Rails apps that are deployed using Passenger or a Mongrel cluster where requests are handled in separate processes, not in separate threads.

For small to medium-sized applications you'll probably do fine with the default file store. If you need to scale beyond that, you should have a look at ActiveSupport::Cache::MemCacheStore.

Pär Wieslander
@Pär Wieslander, thanks for your answer. I was a Java developer, and I thought rails is like java, one process and many threads. Do you mean, when a request comes, there is exactly one process(so one thread) to handle it? If I want a globe cache, I have to consider other cache product, like 'memcached'?
Freewind
@Freewind: There are several processes, but each process only handles one request at a time. I suggest that you start with a `FileStore` cache. It is a global cache that usually doesn't require any additional configuration, so it's easy to get started with. You can always switch to `memcached` later on if the need arises, but since it requires additional configuration (you have to keep a `memcached` server running), it's easier to start with a `FileStore` and only switch to `memcached` later on if you need to.
Pär Wieslander
+1  A: 

Most deployment scenario's for Rails are actually single-threaded. Concurrency is achieved by spawning multiple processes, either automatically or beforehand. For many people, thread-safety won't matter that much.

Multi-threaded options do exist (especially with JRuby), so your question is still valid. Which is why in Rails 3, the old ActiveSupport::Cache::MemoryStore has been removed and replaced with ActiveSupport::Cache::SynchronizedMemoryStore, making it thread-safe by default.

If you need the thread-safety in a Rails 2 app, put the following somewhere in your environment.

ActionController::Base.cache_store = :synchronized_memory_store
molf
@molf, I was a Java developer, so I maybe misunderstood about rails. Do you mean: when a new request coming, rails will open a new process, not a thread, to handle it? So, no matter it's thread-safe or not, it is not very useful(except jRuby). If I want to use a globe memory cache, I should not use them?
Freewind
@Freewind: Yes, that's right. As both molf and I answered, requests are usually handled in separate processes. Often you have a pool of worker processes, and each new request goes to the first process that's not busy with another request. So yes, if you want a global cache you should go with for example `FileStore` or `MemCacheStore` which both work across processes.
Pär Wieslander
Thank you both very much, I get it :)
Freewind