I'm experimenting to understand a problem in production, so I've thrown this snippet inside a controller action in dev to test:

start =
num_threads = 6
results =
saved_results = []
threads = []
connections = []
semaphore =

# start threads
(1..num_threads).each do |i|
  threads << do
    #semaphore.synchronize { connections << ActiveRecord::Base.connection } # for cleanup?

    #ActiveRecord::Base.connection.execute("select sleep(1.6);")   # runs sequentially
    sleep(1.6)                                                    # runs concurrently
    result = User.find_by_id(i)
    results << [i, result]

# end option 1 - let everyone finish

# end option 2 - simulate early exit condition
#while saved_results.count < 3 do saved_results << results.pop end

# cleanup/close open connections?!)

elapsed = - start
render :text => [ elapsed.to_s, saved_results.size, results.size ].join(", ")

sleep(1.6) executes in approximately 1.6 seconds, as expected.

However, the ActiveRecord select sleep(1.6); takes 6 * 1.6 = 9.6 seconds, despite mysql console show processlist; displaying that independent connections are opened for each thread*.

What's going on? Why won't the ActiveRecord queries run concurrently? I've also experienced this in production console.

I do have config.threadsafe! set in config/environment.rb. If it matters, I'm using Rails 2.3.

*These connections have to be manually closed? Production always has a lot of open connections that are doing nothing, causing Mysql::Error: Too many connections. I'll probably submit this issue as a another question.

Was it helpful?


Some remarks:

  • rails 2.3 itself is afaik itself not really threadsafe, since rails 3.x it is. But for this case that does not really matter I think.
  • you should be using ruby 1.9 at least. The "green threads" in 1.8 are less than optimal. While treading in ruby 1.9 still is not optimal, it is better. For real threading you should check out jruby or rubinius (no GIL).
  • you should be using the mysql2 gem. The mysql gem keeps the GIL while waiting for a response from the database.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top