RailsでPromisesやFutureを使う方法
共通して注意すること
- 並列処理中に動的クラス解決させない
- value!を使う
並列処理中に動的クラス解決させない
Concurrent::Promises.future
内部で動的クラス解決を行おうとすると、
Circular dependency detected while autoloading constant
というエラーが出てしまう。
回避策としては事前にRails.application.executor.wrap
の前でMyClass
を宣言して動的クラス解決を事前にさせること。
MyClass Rails.application.executor.wrap do Concurrent::Promises.future do MyClass.async_something end end
value!を使う
参考のところにも書いてあるが、value!
を利用しないとエラーハンドリングから漏れることに注意。
Promises.future
※プロセス数管理は勝手にやってくれるやつ
※eachだか lazyだかで大量に回そうとするとプロセスが作れなくなるのかセグフォするので注意↓
※(version ruby 2.5.3, rails 5.0?)
Rails.application.executor.wrap do Concurrent::Promises.future do :async_something end end ActiveSupport::Dependencies.interlock.permit_concurrent_loads do Concurrent::Promises.zip(*tasks).value! end
Future.execute
※ こちらはプロセス数に個数制限を掛けられるのでeachやlazyで雑に回せる
thread_pool = Concurrent::FixedThreadPool.new(20) Rails.application.executor.wrap do Concurrent::Future.execute({ executor: thread_pool }), do :async_something end end ActiveSupport::Dependencies.interlock.permit_concurrent_loads do executors.map(&:value!) end
参考: