LoginSignup
5
3

Railsのdelayed_jobがわけわかめなのでメモメモ

Last updated at Posted at 2023-09-15

どうもこんにちは。

今回はRailsアプリケーションで使用しているdelayed_jobについてメモしていきます。

delayed_jobってなに?

delayed_jobとは、「バックグラウンドで非同期処理をしてくれるrailsのライブラリ」です。

何に使えるかっていうと、「大量のジョブを処理する時」に使えます!

一番わかりやすい例だと、大量のメール送信を一度に行うとかなり時間がかかってしまうため、小分けにして送信していくという手法をとるために最適です。

導入方法

導入はGemを使用して行います。

1. Gemの追加

Gemfileに以下のコードを記述します。

gem 'delayed_job_active_record'

2. bundle installの実行

ターミナルでbundle installを実行します。

3. マイグレーションファイルの作成

ターミナルでrails generate delayed_job:active_recordを実行します。

Delayed_jobは、DB上にテーブルを作成してジョブを管理しています。
DBにアクセスすれば溜まっているジョブを確認することもできます。

4. マイグレーションの実行

ターミナルでrails db:migrateを実行します。

5. ジョブの実行方法を設定

config/application.rbに以下を記述します。
これによって、ActiveJobのバックエンドとしてdelayed_jobを使用するように指定できます。

class Application < Rails::Application
    # ...
    config.active_job.queue_adapter = :delayed_job
    # ...
end

6. ジョブの実行/停止

以下をターミナルで実行して、delayed_jobワーカーを起動して、ジョブを実行します。

bin/delayed_job start

また、停止するときは以下のコマンドです。

bin/delayed_job stop

使用方法

自分が使用している目的は、メール送信を小分けにして送信することです。今回はそれの使用方法について説明します。

メール送信機能の実装

ある機能のあるタイミングでメール送信ジョブが実行されるようにコードを書いていきます。

以下のコードをメール送信したいタイミングのコントローラに記述します。(例えばコメント登録の後とか。。。)

addresses = ["test01@mail.com", "test02@mail.com", "test03@mail.com"]
addresses.each do |address|
    NotificationMailer.send_mail(address).deliver_later
end

次に、app/mailers/application_mailer.rbに以下のコードを記述します。

class ApplicationMailer < ActionMailer::Base
  default from: 'TEST <noreply@test.net>'
  layout 'mailer'
end

次に、app/mailers/notification_mailer.rbsend_mailメソッドを定義します。

class NotificationMailer < ApplicationMailer
  default from: 'TEST <noreply@test.net>'

  def send_mail(send_to_address)
    return if send_to_address == []

    mail(to: send_to_address, subject: "テストメールです。")
  end
end

最後に、app/views/notification_mailerディレクトリにsend_mail.html.erbを作成して、以下のように記述します。

<!DOCTYPE html>
<html lang="ja" dir="ltr">
    <head>
        <meta content='text/html; charset=UTF-8' http-equiv='Content-Type'>
    </head>
    <body>
        <h3><%= "テストメールです。" %></h3>
        <p>これはテスト〜\nメール送信のテスト~</p>
        <br>
    </body>
</html>

バッチ処理実装

次は、ジョブが実行されるようにバッチ処理を組みます。

バッチ処理には、wheneverというGemを導入する必要があります。

その手順は以下の記事でわかりやすく説明されていたので、そちらを参照してください。

wheneverの設定の中で、configディレクトリにconfig/schegule.rbというファイルを作成したと思います。

そこに、Production環境で実行したいコマンドを記述します。(以下は5分おきに実行するという例です。)

every 5.minute do
  command "cd /var/app/current && export $(cat /opt/elasticbeanstalk/deployment/env) && bin/delayed_job start"
end

これで5分おきにDelayed_jobが実行されるようになりました。

メール送信の指令はどのようにしてジョブのキューに入るの?

キューとは、ジョブの待ちタスク見たいなものです。

今回の例では、コントローラから「メール送信してくれー」と指示を出しましたが、実はdeliver_laterというメソッドがジョブのキューに入れる役割をしています。

そのため、メールが送信されるまでの順番はこうなります。

スクリーンショット 2023-09-14 19.08.01.png

デプロイ時に必要な操作

仕上げにデプロイ時に以下のコマンドを実行する必要があります。

# cronを書き換え
bundle exec whenever --update-crontab

# 正常に書き換えられているか確認
bundle exec crontab -e

これは、setupファイルを作成して自動実行でも、ssh接続してコマンド実行でもなんでもOKです。

まとめ

今回はdelayed_jobについて紹介しました。

まだ理解が浅いので、ちょくちょく記事は書き換えると思いますが、参考になったらいいなぁと思います。

以上

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3