Help us understand the problem. What is going on with this article?

【Rails】ActiveJob/DelayedJobを使いこなす【基本】

More than 3 years have passed since last update.

Job, Active Job, Delayed Jobとは

Job

メールの送信、データのインポート/エクスポートなどの時間のかかる処理を適した方法でバックエンドで行うためのコンセプト。

Active Job

Sidekiq, Resque, Delayed Jobといった実際にバックグラウンドでジョブを実行するgemの差分をほぼ意識しないでジョブを扱えるようにするための、ジョブのインフラ。

Delayed Job

上記のバックエンド処理を行うために使われるメジャーなgemの一つ。(他のgemとの比較記事: http://qa.atmarkit.co.jp/q/2406)

具体例から見るメリット

例: メール送信

◯ Jobを使わずに、メール送信(deliver)を行う場合

app/controller/email_controller.rb
  ...
  def deliver
    @email = Email.find(params[:id])
    @email.deliver #deliverというインスタンスメソッドで送信できるとする。
    redirect_to complete_email_url
  end
  ...

こんな感じで、redirectするまでに、メールがdelverされるのを待つ必要がある。

◯ Delayed Jobを使う

app/controller/email_controller.rb
  # Controller(その場)で実行
  @email.deliver

  # Job(バックエンド)に委託する
  @email.delay.deliver

この一部分を上記のように、変更すると、controller上では、バックエンドに委託したら先にいけるので、サクッと次のredirectの処理までいける!userを待たせなくて良い!という。Delayed Jobを使うと書き方もシンプルで便利っすね〜。

◯ Active Jobと連携して使う

As I mentioned, Active Jobは、実はgemたちの後から、Railsに導入されたgemごとの操作方法を統一できるJobのインフラ。ここでは、その統一された方法で、Delayed Jobを扱うこと方法を考える。

  1. アプリ側で時間のかかる処理を、それぞれのJob Classを定義してそちらに移行。
  2. アプリ側から、そのJob Classを呼び出す。
app/jobs/email_deliver_job.rb
# Job Classの定義
class EmailDeliverJob < ActiveJob::Base
  queue_as :default

  def perform(email_id)
    # controller(アプリ側)で行っていた処理(以下)が移動された
    Email.find(email_id).deliver
  end

end
app/controllers/email_controller.rb
  # controller(アプリ側)でEmailDeliverJob(定義したJobClass)を呼び出す
  ...
  def deliver
    EmailDeliverJob.perform_later(params[:id])
    redirect_to complete_email_url
  end
  ..

これで、先ほど同様、バックエンドに重い処理任せてcontrollerは先に進めるというわけですね。

これまで見てきた、重い処理をJobに委託することを、"Jobを登録する(enqueue)"という。


Active Jobと連携するときにしなくてはいけない細かい設定たち
  1. どのgemを使うのかアプリに教える
config/apprication.rb
  ...
    config.active_job.queue_adapter = :delayed_job
  ...
  1. Jobの作成
    以下のコマンドでJob作成。
  rails g job EmailDeliver

作成されるapp/jobs/email_deliver_job.rbが先ほど出てきたJob Classの記述を持つ。


使い方 3ステップ

1. DelayedJob(gem)のインストール

  # Gemfileに。
  gem 'delayed_job_active_record'
  # で、インストール
  bundle install

Jobを管理するテーブルを作成する。

  rails g delayed_job:active_record
  rake db:migrate

2.ジョブを登録する(enqueue)

"具体例からみるメリット"を参照。

3.Jobを実行する(workerの起動)

rake taskでworkerを起動し、Jobを処理する。これが起動されるまでは、Jobは処理されないので要注意。委託業者を起動させる感じだね。

rake jobs:work

(本番時は、daemonsというgemでworkerを走らせる。https://github.com/ghazel/daemons)

応用

  • コールバックを使う(http://railsguides.jp/active_job_basics.html) Jobのenqueue前後、perform前後などに行うlogicを指定できる。
  • その他もありそう。参照先をよく読むとありそう。

参照先
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした