RailsでrakeタスクとJobを使った非同期処理の基本を学んだ
Railsで開発を進める中で、rakeタスク と Job を使った非同期処理を触る機会がありました。
これまで何となく名前は知っていたもののRailsドキュメントだけでなく実際に使ってみて役割や流れが少し理解できたので、個人用の学習記録として残します。
まず理解したこと
今回触ってみて、ざっくり以下のように整理できました。
-
rakeタスク
- 定期実行したい処理
- 一括更新したい処理
- 手動でまとめて実行したい処理
-
Job
- すぐにレスポンスを返したい画面処理の裏側で動かしたい処理
- 時間がかかる処理
- メール送信や集計処理など、非同期で回したい処理
最初はどちらも「裏で動く処理」くらいの認識でしたが、
実際には 役割が少し違う ことが分かりました。
Jobの基本的な使い方
たとえば、時間のかかる処理をそのままコントローラーで実行すると、ユーザーが画面上で待つ時間が長くなってしまいます。
そのため、重たい処理はJobに切り出して、後ろで実行させる形にします。
Jobの例
# app/jobs/sample_job.rb
class SampleJob < ApplicationJob
queue_as :default
def perform(user_id)
user = User.find(user_id)
Rails.logger.info "開始: #{user.name}"
# 時間がかかる処理のイメージ
sleep 5
Rails.logger.info "終了: #{user.name}"
end
end
呼び出し側の例controllerなど
SampleJob.perform_later(current_user.id)
ここで理解できたのは、perform_later を使うことで、
その場ですぐ処理を完了させるのではなく、Jobとして後ろに渡す という流れです。
反対に、その場で即実行するなら perform_now ですが、
非同期で動かしたいなら perform_later を使う、という違いも整理できました。
rakeタスクの基本的な使い方
次に、定期実行や一括更新向きなのがrakeタスクです。
たとえば、毎日まとめてデータ更新したい処理などは、rakeタスクにしておくと管理しやすいと感じました。
rakeタスクの例
lib/tasks/sample.rake
namespace :sample do
desc "ステータスを一括更新する"
task update_status: :environment do
User.where(active: true).find_each do |user|
user.update!(status: "updated")
puts "#{user.name} を更新しました"
end
end
end
実行コマンド
bin/rails sample:update_status
この形で書くことで、Railsの環境を読み込んだ上でまとめて処理を実行できることが分かりました。
今回の学び
今回触ってみて、自分の中では次のように整理できました。
画面操作に紐づく重い処理はJob
定期実行や一括処理はrakeタスク
非同期にしたい時は、処理をその場で全部やろうとせず、役割ごとに切り出して考える
以前は「非同期処理」と聞いて少し難しく感じていましたが、
実際にコードを書いてみると、
どの処理をその場でやるのか、どの処理を後ろに回すのかを整理する考え方が大事 だと分かりました。
まとめ
まだ実務レベルで使いこなせる段階ではありませんが、
今回の学習で rakeタスク と Job の基本的な役割と流れはかなり見えやすくなりました。
今後触る機会があれば、Jobのリトライ、queueの使い分け、定期実行との組み合わせあたりも少しずつ理解を深めていきたいです。