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

【Rails】Active Jobについてゼロから理解する

概要

RailsのActive Jobについてゼロから理解する為に調べたことをまとめます。

  • 本格的なアプリでは往々にして時間のかかる処理が発生する
    • 大量のデータ集計、外部サービスとの連携、メール送信など
  • そしてこれらの処理はリアルタイムに完了してなくても良い場合もある
  • アプリから実行すべき処理(ジョブ)待ち行列(キュー)に登録して後から実行(非同期実行)することで、アプリのレスポンスを改善できる!

  • Active Jobとは、そのようなジョブの管理から実行までの管理する為のモジュール

    • Active Jobそのものは、基本的に、ジョブ操作の為のインタフェース(メソッド名などの決まりごと)を提供しているに過ぎない
    • 実際にジョブを実行するのはジョブ管理ライブラリの役割(Delayed JobSidekiq
  • アダプターを切り替えれば、アプリケーションをほとんど改修することなくバックエンドのジョブ管理ライブラリを自由に切り替えられる

やってみた

delayed_jobを利用する

delayed_jobをインストールする

  • Gemfileに追記
gem 'delayed_job_active_record'
  • bundle install
$ bundle install
  • delayed_jobび必要なファイルを生成
$ bundle exec rails generate delayed_job:active_record
      create  bin/delayed_job
       chmod  bin/delayed_job
      create  db/migrate/20200121063912_create_delayed_jobs.rb
  • マイグレを打ってdelayed_jobsテーブルを追加
    • 非同期で実行する処理を一時的に管理するテーブル
$ bundle exec rails db:migrate
== 20200121063912 CreateDelayedJobs: migrating ================================
-- create_table(:delayed_jobs, {:force=>true})
   -> 0.0292s
-- add_index(:delayed_jobs, [:priority, :run_at], {:name=>"delayed_jobs_priority"})
   -> 0.0226s
== 20200121063912 CreateDelayedJobs: migrated (0.0519s) =======================
  • Active Jobでdelayed_jobを有効にする(config/application.yaml)
    # using delayed_job
    config.active_job.queue_adapter = :delayed_jo

ジョブを動かしてみる

  • ジョブを作成する
$ bundle exec rails g job Sleep
      create  app/jobs/sleep_job.rb
  • 生成されたジョブを編集する
    • performメソッドがジョブの実処理を表す
    • メソッド配下に非同期実行する処理を記述する def perform() puts("start sleep") sleep 10 end
  • ジョブを登録してみる(rails consoleから)
    • ジョブを登録するにはクラス名.perform_later(...)とする
    • これでジョブをキューに登録しなさい、という意味になる
    • テストでジョブを即座に実行したい場合はperform_now()を利用する
irb(main):002:0> SleepJob.perform_later()
   (0.4ms)  SET NAMES utf8mb4,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
   (0.2ms)  BEGIN
  Delayed::Backend::ActiveRecord::Job Create (0.9ms)  INSERT INTO `delayed_jobs` (`handler`, `run_at`, `queue`, `created_at`, `updated_at`) VALUES ('--- !ruby/object:ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper\njob_data:\n  job_class: SleepJob\n  job_id: 6643be62-59fd-4ea3-81a1-c14fcd13aafb\n  provider_job_id: \n  queue_name: default\n  priority: \n  arguments: []\n  executions: 0\n  exception_executions: {}\n  locale: en\n  timezone: UTC\n  enqueued_at: \'2020-01-21T06:53:15Z\'\n', '2020-01-21 06:53:15', 'default', '2020-01-21 06:53:15.343196', '2020-01-21 06:53:15.343196')
   (0.4ms)  COMMIT
Enqueued SleepJob (Job ID: 6643be62-59fd-4ea3-81a1-c14fcd13aafb) to DelayedJob(default)
=> #<SleepJob:0x00007f9cf4c456d8 @arguments=[], @job_id="6643be62-59fd-4ea3-81a1-c14fcd13aafb", @queue_name="default", @priority=nil, @executions=0, @exception_executions={}, @provider_job_id=1>
  • delayed_jobを起動してキューに登録されたジョブを実行する
$ bundle exec bin/delayed_job start

ジョブ実行のカスタマイズ

delayed_jobの動作パラメータ

  • config/initializer配下にdelayed_job.rbのような初期化ファイルを作成
    • delay_jobs:ジョブの遅延実行を有効化するか
    • max_attemps:最大リトライ回数
    • max_run_time:最大実行回数
    • destroy_failed_jobs:失敗したジョブを破棄するか
    • read_ahead:一度に読み込むジョブの個数
    • sleep_delay:実行ジョブがない場合のsleep期間

キューの名前を設定する

  • キューを分けることで、特定のキューだけを優先して実行するなどの仕分けが可能になる
    • queue_asメソッドを利用する
    • queue_name_prefixパラメータでprefixを宣言する
    • setメソッドを利用する
irb(main):006:0> SleepJob.set(queue: :sleep).perform_later()

コールバック

ジョブを登録/実行するタイミングで実行されるメソッド、またはその仕組のこと

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
ユーザーは見つかりませんでした