letter_opener でメールを受信できない、、、あ、ジョブ管理ライブラリ起動してなかったからか

January 16, 2021

こんにちは。

とある日仕事をしていて、、、

「なんで会員登録のメールはすぐに受信するのに、こっちの処理で飛ばしてるはずのメールはすぐに受信できないんだろう?」と不思議がっていました。

で、先輩に質問すると、、

「メールとか、重い処理は本流からはずれて処理をするんだよ。bundle exec rake job:workをローカルで実行すれば、メールを確認できるはずだよ」

と言われて、そのとおり実行すると、無事にメールを受信できて、開発が前進しました。

ということで本記事は、ジョブ管理のお話。

ActionJob というものがある

時間のかかる処理をリアルタイムで行うと、その間、ユーザーは待たされてしまいます。大量データの集計処理や外部サービスの連携、そしてメール送信などが例に挙げられます。

リアルタイムで行う必要がない処理もあります。そのような処理(ジョブ)は待ち行列(キュー)に登録しておき、あとから実行(非同期実行)することで、アプリ本体のレスポンスを改善できます。

標準実装されている ActionJob はジョブの登録から実行までを管理するためのモジュールです。ただし、ActionJob それ自体は、ジョブ操作のためのインターフェースにすぎません。

実際にジョブを実行するのは、サードパーティから提供されているジョブ管理ライブラリです。たとえば、

  • Delayed Job
  • Sidekiq

などがあります。詳しくは下記参照。

[https://api.rubyonrails.org/v6.1.0/classes/ActiveJob/QueueAdapters.html:title]

上記の説明は、下記の本の pp 536 参照。

[https://www.amazon.co.jp/Ruby-Rails-5%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B/dp/4774188832:embed:cite]

アダプターを切り替えると、アプリのコードをそれほど修正しなくても、ジョブ管理ライブラリを変更できます。便利!

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のようです。

[https://github.com/collectiveidea/delayed_job/blob/5ac5adea8d18325d0470eeebfa81227b1f5961e3/README.md:embed:cite]

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 と非同期処理について理解が深まったので良しとしよう。

参考文献

[https://www.htmlhifive.com/conts/web/view/study-room/async-programming-with-deferred:title]

[https://qiita.com/kiyodori/items/da434d169755cbb20447:title]

[https://stackoverflow.com/questions/45481751/bundle-exec-rake-jobswork:title]

[https://qiita.com/shunsuke227ono/items/c29119a348f120c5c13a#comments:title]

[https://railsguides.jp/action_mailer_basics.html#%E3%83%A1%E3%82%A4%E3%83%A9%E3%83%BC%E3%82%92%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%99:title]

[https://www.amazon.co.jp/Ruby-Rails-5%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B/dp/4774188832:title]

[https://www.amazon.co.jp/%E3%83%91%E3%83%BC%E3%83%95%E3%82%A7%E3%82%AF%E3%83%88-Ruby-Rails-%E3%80%90%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88%E3%80%91-Perfect/dp/4297114623/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E3%83%91%E3%83%BC%E3%83%95%E3%82%A7%E3%82%AF%E3%83%88rails&qid=1610760551&s=books&sr=1-1:title]