【増補改訂版】パーフェクト Ruby on Rails を読む - その3

【増補改訂版】パーフェクト Ruby on Rails を読んだので、頭が整理できた部分をなるべく自分の言葉でまとめていきます。

第1章、第2章の内容については以下を御覧ください。

【増補改訂版】パーフェクト Ruby on Rails を読む - その1 - readengineerのブログ

第3章の内容については以下を御覧ください。

【増補改訂版】パーフェクト Ruby on Rails を読む - その2 - readengineerのブログ

5 章

Rails 標準の機能を活用して素早く機能実装する

Rails は「利用頻度は高くないが、0 から実装しようとすると時間がかかるもの」を標準機能として提供している。

Active Job による非同期実行
非同期処理実行処理機能を提供するもの。実行処理を別のインフラに任せることができる。インフラは多様なものを選べるが、その処理内容の定義を統一化してくれるもの。

bin/rails g job ジョブ名 のようなスクリプトを実行すると、ジョブを定義するファイルが app/jobs/* に生成される。

class TestJob < ApplicationJob
  queue_as :default

  def perform(*args) # 引数は変更できる。例えば def perform(name) とか
    # Do something later 
    puts 'hello' # ここではモデルの操作なんかもできる。
  end
end

rails console を起動して、以下のように実行してみることができる。
アダプターというものを介してバックエンドと接続・切替をしており、デフォルトのアダプタは async というもので、Rails のプロセス中のスレッドを利用して実行するもの。

perform_later メソッドはバックエンドのキューに積んでくれる。
async を使うとメモリ内にキューが保管されているため、再起動するとキューが消えてしまう。

irb(main):002:0> TestJob.perform_later
Enqueued TestJob (Job ID: 9e2dc5d2-7289-4e33-a907-4f09e61dd80b) to Async(default)
=> 
#<TestJob:0x00007fa492970cc8
 @arguments=[],
 @exception_executions={},
 @executions=0,
 @job_id="9e2dc5d2-7289-4e33-a907-4f09e61dd80b",
 @provider_job_id="f5a5625e-0f71-4372-90c5-b7d8aae8f4c8",
 @queue_name="default",
 @timezone="UTC">
irb(main):003:0> Performing TestJob (Job ID: 9e2dc5d2-7289-4e33-a907-4f09e61dd80b) from Async(default) enqueued at 2021-12-14T00:23:55Z
hello
Performed TestJob (Job ID: 9e2dc5d2-7289-4e33-a907-4f09e61dd80b) from Async(default) in 0.07ms

実行日時の設定や、メソッドが呼ばれてから実行するまでの待機時間の設定、同期的な実行方法など、多様な設定が可能。

キューを永続化したいときは、Redis を利用したジョブキュー管理を行ってくれる Sidekiq や resque などの gem を使うことになる。

注意点としては、Active Job を利用して基本的な機能を利用することができるが、一部でバックエンドの機能が利用できない場合があるらしい。例えば sidekiq pro などで提供している機能とか。
バックエンドを差替える必要が出てくる場合や、Active Job に依存している場合などは Active Job を利用する必要性があるが、できないことがあることも知っておく必要がある。