railsのactivejobアダプターのAsyncAdapterって何?実装は?本番に使える?実用性は?調べてみました。
はじめに
AsyncAdapterってのは、activejobアダプターの1つでオンメモリで完結するジョブキューワーカー。
config.active_job.queue_adapter = :async
「即時実行」と「指定した時間の経過後に実行」が選べる。
ミドルウェアなしで非同期ジョブを実現できて開発環境やテスト環境での使用が推奨されている。本番で向かない理由は後述する。
実装は?
このオンメモリでのジョブキューは、concurrent-rubyのScheduledTaskで実装されている。
実装シンプルで、AsyncAdapter内にSchedulerとJobWrapperクラス内でScheduledTaskのメソッドで構成している。
本番で使えるの?実用性は?
結論は本番では使ってはいけない。
メール送信とかログ的な記録が向いている、とAsyncAdapterと同様なアーキテクチャの https://github.com/brandonhilkert/sucker_punch のREADMEに書いているが、AsyncAdapteのソースコードには本番での使用は非推奨と書いている。なぜなら、オンメモリなのでキューをロストする可能性があり、実行される保証がないからである。
これは僕の経験なんですが、非同期処理およびマルチスレッドはエラートラッキングサービスに送信されずに失敗しているということがあったり、WEBプロセスのスレッドとして実行していると、WEBのログに非同期ジョブのログが混ざるわけなのでエラー発生時の検出が非常に困難。それと、WEBと非同期ジョブが1プロセス上でリソースを共有しているため不具合時の切り分けができない、などの運用時の欠点がある。 9割くらいは成功するだろうけど、残りの1割での失敗が許容されるなら採用してもいいと思う。
運用面ではnotコンテナ運用でのデプロイ時だけにジョブが失敗するとかも可能性もあるし、データストアを使っていないので実行したジョブの一覧を画面から見る事もできない。メールの送信可否を確認することが難しい。
繰り返しになるけど、どうでもいい処理だったら使ってヨシ。
おわり。