Is active record 3.1.1 supposed to be threadsafe?

Hi There

Is active record 3.1.1 supposed to be threadsafe? In other words, should the following (concurrent access to a model) work?

Thread.new do MyModel.where(some_condition).first end Thread.new do MyModel.where(some_condition).first end

I ask because upon the answer, it depends which component should handle synchronization, and in consequence, which component to patch/fix.

A bit of background: We stumbled over a concurrency issue when using capybara-webkit with rails3.1. We traced the issue down to one thread querying and trying to accessing the cache while another thread cleared the same cache. Assuming active record 3.1.1 is supposed to be threadsafe, then the culprit for the issue would be ActiveRecord::ConnectionAdapters::QueryCache, which doesn't synchronize access to its @query_cache. See https://github.com/awd-switzerland/rails/commit/22aeda0f0553fdcabca156012b67f2aa2add293c for a possible way to resolve that. However, I'm not sure in which layer the rails team wants to handle synchronization. Also notice that the patch is naive in that it simply assumes thread support in ruby to be enabled.

Best regards Stefan Rusterholz

Hi There

Is active record 3.1.1 supposed to be threadsafe? In other words, should the following (concurrent access to a model) work?

Thread.new do MyModel.where(some_condition).first end Thread.new do MyModel.where(some_condition).first end

I ask because upon the answer, it depends which component should handle synchronization, and in consequence, which component to patch/fix.

Rails added thread safety back in 2.1 or 2.2 so current versions should be threadsafe.

A bit of background: We stumbled over a concurrency issue when using capybara-webkit with rails3.1. We traced the issue down to one thread querying and trying to accessing the cache while another thread cleared the same cache. Assuming active record 3.1.1 is supposed to be threadsafe, then the culprit for the issue would be ActiveRecord::ConnectionAdapters::QueryCache, which doesn't synchronize access to its @query_cache. Seehttps://github.com/awd-switzerland/rails/commit/22aeda0f0553fdcabca15… for a possible way to resolve that. However, I'm not sure in which layer the rails team wants to handle synchronisation.

In theory I don't think this is needed because different threads should be using different connection objects (there's supposed to be a pool of connection objections, and any member of the pool is only ever used by one thread at a time. You might also want to ask on the rails- core list

Fred

Frederick Cheung wrote in post #1028961:

In theory I don't think this is needed because different threads should be using different connection objects (there's supposed to be a pool of connection objections, and any member of the pool is only ever used by one thread at a time. You might also want to ask on the rails- core list

Seems practice disagrees with that theory. At least we had exceptions due to unsynchronized cache access. And we ourselves did not introduce any threads in the code. I'll see whether I get answers here. If not, I'll gladly accept your advice and take it on to rails-core.

Best regards Stefan

Frederick Cheung wrote in post #1028961:

> In theory I don't think this is needed because different threads > should be using different connection objects (there's supposed to be a > pool of connection objections, and any member of the pool is only ever > used by one thread at a time. You might also want to ask on the rails- > core list

Seems practice disagrees with that theory. At least we had exceptions due to unsynchronized cache access. And we ourselves did not introduce any threads in the code. I'll see whether I get answers here. If not, I'll gladly accept your advice and take it on to rails-core.

It might also be related to QueryCache/ConnectionPool thread fix by mjtko · Pull Request #1670 · rails/rails · GitHub

Fred