覚書: Rails: Action Mailer の deliver_later

Action Mailer の deliver_later(メールキューにメールを登録)についての覚書です。

# 保存後にUserMailerを使ってwelcomeメールを送信
UserMailer.with(user: @user).welcome_email.deliver_later

Action Mailer の基礎 - Railsガイド

Notifier.welcome(User.first).deliver_later Notifier.welcome(User.first).deliver_later(wait: 1.hour) Notifier.welcome(User.first).deliver_later(wait_until: 10.hours.from_now) Notifier.welcome(User.first).deliver_later(priority: 10)

ActionMailer::MessageDelivery

本題に入る前に

リクエスト-レスポンスのサイクル

URL を開くと Controller が View を返す。

リクエスト-レスポンスのサイクル

メール送信

Mailer の deliver_now 呼ぶと、メールを送信する。
Mailer はグローバルIDで Model を参照できる。

deliver_now(今、配信する)

ジョブ

Job は Controller とは別スレッドまたは別プロセスで動く。
Job はクラス名で自身を永続化する。
Job もグローバルIDで Model を参照できる。

ジョブキューを使った遅延実行

deliver_later

デフォルトで MailDeliveryJob を使う。

deliver_later(後日配信する)

MailDeliveryJob
Mailer のクラス名と Model のグローバルIDを永続化する。
Job 自身クラス名で永続化している。


後日、Visual Studio Code でデバッグ実行して動作確認してみました。


以下、コードを読んだ際のメモ。

このwelcome_emailメソッドはActionMailer::MessageDeliveryオブジェクトを1つ返します。このオブジェクトは、そのメール自身が送信対象であることをdeliver_nowやdeliver_laterに伝えます。

Action Mailer の基礎 - Railsガイド

ActionMailer::MessageDelivery
https://github.com/rails/rails/blob/7-0-stable/actionmailer/lib/action_mailer/mail_delivery_job.rb

deliver_later
https://api.rubyonrails.org/classes/ActionMailer/MessageDelivery.html#method-i-deliver_later

def deliver_later(options = {})
  enqueue_delivery :deliver_now, options
end

https://github.com/rails/rails/blob/7-0-stable/actionmailer/lib/action_mailer/message_delivery.rb#L98

def enqueue_delivery(delivery_method, options = {})
  @mailer_class.delivery_job.set(options).perform_later(
    @mailer_class.name, @action.to_s, delivery_method.to_s, args: @args)

以下、本件とは直接関係ありませんが興味深い内容だったのでメモ。

Action Mailerのdeliver_laterにみるRubyのDelegatorの仕組み | Wantedly Engineer Blog
RuntimeError: You've accessed the message before…の箇所も気になったのですが読むと時間がかかりそうだったので助かりました。感謝。

Hangfireで実現する.NETアプリのバックグランドジョブ - 一休.com Developers Blog
静的型付け言語での実現方法が気になったので参考になりました。感謝。

以上です。

この記事が気に入ったらサポートをしてみませんか?