letter_opener でメールを受信できない、、、あ、ジョブ管理ライブラリ起動してなかったからか
こんにちは。
とある日仕事をしていて、、、
「なんで会員登録のメールはすぐに受信するのに、こっちの処理で飛ばしてるはずのメールはすぐに受信できないんだろう?」と不思議がっていました。
で、先輩に質問すると、、
「メールとか、重い処理は本流からはずれて処理をするんだよ。bundle exec rake job:work
をローカルで実行すれば、メールを確認できるはずだよ」
と言われて、そのとおり実行すると、無事にメールを受信できて、開発が前進しました。
ということで本記事は、ジョブ管理のお話。
ActionJob というものがある
時間のかかる処理をリアルタイムで行うと、その間、ユーザーは待たされてしまいます。大量データの集計処理や外部サービスの連携、そしてメール送信などが例に挙げられます。
リアルタイムで行う必要がない処理もあります。そのような処理(ジョブ)は待ち行列(キュー)に登録しておき、あとから実行(非同期実行)することで、アプリ本体のレスポンスを改善できます。
標準実装されている ActionJob はジョブの登録から実行までを管理するためのモジュールです。ただし、ActionJobそれ自体は、ジョブ操作のためのインターフェースにすぎません。
実際にジョブを実行するのは、サードパーティから提供されているジョブ管理ライブラリです。たとえば、
- Delayed Job
- Sidekiq
などがあります。詳しくは下記参照。
上記の説明は、下記の本のpp 536参照。
アダプターを切り替えると、アプリのコードをそれほど修正しなくても、ジョブ管理ライブラリを変更できます。便利!
config/application.rb # delyaed_jobの場合 config.active_job.queue_adapter = :delayed_job # sidekiqの場合 config.active_job.queue_adapter = :sidekiq
キューに登録してあるジョブを実行するには
ジョブ管理ライブラリによって違うようなので、利用しているライブラリのGithubを確認しましょう。
delayed_job
の場合は、bundle exec rails jobs:work
のようです。
deliver_now と deliver_later
Action Mailer
によるメール送信にはいくつかのメソッドが用意されています。
deliver_now
は、同期的にその場でメール送信を行うメソッドです。
deliver_later
は、非同期でメールを送信します。これにより、Webのリクエスト/レスポンスサイクルの外でメールを送信できるので、ユーザーは送信完了を待つ必要がないのです。
また、deliver_latar(wait: 5.minutes)
のようにすると5分後に送信するように指示もできます。いろいろなオプションがあるみたいです。
(このメソッドの違いはRUNTEQというプログラミングスクールのカリキュラムにありました、、、身についていなかった、、、oh )
ちなみにログにも、、、
[ActiveJob] Enqueued ActionMailer::DeliveryJob (Job ID: hogehogehogehogeho) to DelayedJob(mailers) with arguments: "Hogehogehoge", "notify_hogehoge", "hogehoge", 33, 44
メール送信の処理(ジョブ)が待ち行列に追加(Enqueued)されたログが表示される。たぶん。
まとめと学び
deliver_later
がメール送信を非同期処理で行うこと、待ち行列のジョブの実行の仕方を知らなかった、という2つの原因が重なって開発が止まってしまった。
ActionJobと非同期処理について理解が深まったので良しとしよう。
参考文献
非同期処理とPromise(Deferred)を背景から理解しよう - hifive
非同期処理ってどういうこと?JavaScriptで一から学ぶ - Qiita
ruby on rails - bundle exec rake jobs:work - Stack Overflow
【Rails】ActiveJob/DelayedJobを使いこなす【基本】 - Qiita
Ruby on Rails 5アプリケーションプログラミング | 山田 祥寛 |本 | 通販 | Amazon
パーフェクト Ruby on Rails 【増補改訂版】 (Perfect series) | すがわらまさのり, 前島真一, 橋立友宏, 五十嵐邦明, 後藤優一 |本 | 通販 | Amazon