Я использую гем Parallel с Rails3 и получаю проблемы с потоками mysql, даже с такой простой строкой, как:
Parallel.each(User.all, :in_processes => 1) { |r| puts r.username }
Поочередно работает, а затем завершается неудачей второй раз. Вот ошибка, которую я получаю:
ruby-1.8.7-p330 :035 > Parallel.each(User.all, :in_processes => 1) { |r| puts r.username }
ActiveRecord::StatementInvalid: Mysql::Error: MySQL server has gone away: SELECT `users`.* FROM `users`
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/connection_adapters/abstract_adapter.rb:202:in `log'
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/connection_adapters/mysql_adapter.rb:289:in `execute'
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/connection_adapters/mysql_adapter.rb:619:in `select'
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/connection_adapters/abstract/database_statements.rb:7:in `select_all'
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/connection_adapters/abstract/query_cache.rb:56:in `select_all'
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/base.rb:467:in `find_by_sql'
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/relation.rb:64:in `to_a'
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/relation/finder_methods.rb:143:in `all'
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/base.rb:439:in `__send__'
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/base.rb:439:in `all'
from (irb):35
from (null):0
Если я делаю непараллельную версию, она отлично работает:
User.all.each { |r| puts r.username }
Я использую самоцвет mysql, но пробовал mysql2 и mysqlplus.
Работает на OSX.
Я думаю, проблема в том, как ActiveRecord и гем mysql работают с потоками.
Из того, что я прочитал, может быть, мне нужно настроить параметры mysql, чтобы сделать его более удобным для параллелизма. Хотя альтернативные гемы, кажется, лучше справляются с обработкой параллелизма.
Я поднял это как запрос к гему - https://github.com/grosser/parallel/issues/9#comment_844380 - но это больше похоже на фундаментальный вопрос о том, как настроить mysql с ruby для одновременного доступа ...
Итак, мой вопрос - есть ли определенная конфигурация для Rails3 и mysql для одновременного доступа к БД?
Спасибо, Крис
EDIT
То, что, кажется, работает, разбивается на 2 запроса: один для получения идентификаторов, затем циклический просмотр идентификаторов параллельно и внутри цикла, повторный доступ к сущности по идентификатору.
ids = User.all.map { |u| u.id }
Parallel.each(ids, :in_processes => 1) do |uid|
ActiveRecord::Base.connection.reconnect!
r = User.find(uid)
puts r.username
end