背景
- Rails4.2, ruby2.3系
- 集計のためにRakeタスクで並行処理を行う必要があった
- Parallelを採用し、並行処理を実装した
-
Circular dependency detected while autoloading constant
エラーが発生し困った - 調べるとeager_load_paths設定しようって書いてあって、やったけど解決しなかった
エラーの原因
1. Autoloadingはスレッドセーフじゃない
- マルチスレッド処理するとCircular dependency起こる。
- ActiveSupport::Dependenciesあたりを参照
- 関連issue
- 関連stackoverflow
2. rakeタスクはデフォルトでeager_loadがfalseになり、Autoloadしちゃう
- config/application.rbに以下の表記をふと発見
- eager_load設定いくらしてもうごかなかったのはこれが理由
config/application.rb
# Rake tasks automatically ignore this option for performance.
対策
- taskの始まりに
Rails.application.eager_load!
を追加する- taskの外に追加するとうまくいかないので注意
task 'resque:setup' => :environment do |task|
Rails.application.eager_load!
# ここに並行処理
end
その他参考になったやつ
- autoloadとeager_loadとproductionとdevelopmentの話