1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

good_jobを導入して定時実行のジョブ(cron)を実装する手順、全体像

Posted at

実装に必要な最低限の知識

good_jobとは
Ruby on Railsアプリケーションでバックグラウンドジョブを実行するためのGemです。


good_jobはActive_jobを基本としているので、忘れていたらActive_jobについてさらっと目を通すと理解が深まります。

実際の手順

未来の自分のために手順をそのまま残しておきます。

初期設定

gemを導入

gem 'good_job'
bundle install

good_jobがRailsアプリケーションに統合されるための初期設定

ターミナルでコマンドを実行します。

bundle exec rails generate good_job:install

このコマンドで、いくつかファイルがgenerateされます。
まず1つ目にマイグレーションファイルが生成されます。

先ほどの記事の内容になりますが、
ジョブを実行する際は通常、Ruby on Railsアプリケーションの他にバックエンドインフラを起動して準備しておく必要です。
good_jobではApplicationで使用しているデータベースでキューを管理することができるようにするので、そのために必要なジョブテーブルをDBに作成するためのマイグレーションファイルが作成する必要があります。

ということでマイグレーションファイルを生成したらそのままマイグレートします

bundle exec rails db:migrate

2つ目に'config/initializers/good_job.rb'ファイルも生成されます。こちらでgood_jobの設定(定時処理の設定)を行うことができますが一旦スルーします。

ActiveJobのバックエンドをGoodJobに変更

次にconfig/application.rbにてActivejobの実行をgood_jobに変更します。

config.rb
module HogeHogeApplication
  class Application < Rails::Application
      config.active_job.queue_adapter = :good_job # この行を追記
  end
end

これで最低限の初期設定は完了しました。


config/initializers/good_job.rbにて定時にジョブを実行するように設定(cronジョブの設定)

こちらの記事を参考にしました

先ほどのgenerateコマンドで自動生成されたconfig/initializers/good_job.rbに必要な初期設定をしていきます。

good_job.rb
Rails.application.configure do
  config.good_job[:enable_cron] = true # good_jobが実行できる様々なジョブの内、cronを有効にしている
  config.good_job[:cron] = {
    my_hoge_task: { # 有効にしているcronジョブの名前
      cron: '0 0 * * *', # 毎日深夜0時に実行
      class: 'MyHogeTaskJob' # my_hoge_taskジョブで実行するJobクラスを指定
    }
  }
end

good_jobでは、

cron 定期的なスケジュールに沿って実行されるジョブ。cronはギリシャ語で'時間'
one_off  一度だけ実行されるジョブ
retryable  ジョブの実行が失敗した場合に自動的にリトライするジョブ
priority  ジョブに優先順位をつけて自動的にリトライするジョブ
queue ジョブを特定のキューに配置して異なる処理順序などで実行するジョブ

このような種類のジョブを実行することができます。今回は「毎晩深夜0時に実行されるジョブ」を実装したかったのでcronジョブを設定しました。

cron: '0 0 * * *'

については、

  • 0 分: 毎時0分に実行
  • 0 時: 毎日0時(つまり、夜中の12時)に実行
  • * 日: 月のすべての日に実行
  • * 月: 年のすべての月に実行
  • * 曜日: 週のすべての曜日に実行

ということを意味しています。これで定期でジョブを実行するように設定できました。

実際にジョブを実装する

app/jobs/my_hoge_task_job.rbに最低限のジョブを実装します。
こちらのファイルではどのバッチ処理ファイルを行うかを定義して、詳細はバッチ処理専用のファイルに持たせることが一般的らしい

app/jobs/my_hoge_task_job.rb

my_hoge_task_job.rb
class MyHogeTaskJob < ApplicationJob
  queue_as :default #Active Jobフレームワークにおいて、ジョブがどのキューに入れられるかを指定

  def perform
     MyHogeTaskBatch.new.call #詳細を持たせたMyHogeTaskBatchをnewして、callメソッドを実行
  end
end

app/batches/my_hoge_task_batche.rbのcallメソッドに詳細な処理内容を実装。

my_hoge_taks_batch.rb
class MyHogeTaskBatch
  def call
    実行したい処理
  end
end

テストコードについて

spec/jobs/my_hoge_task_job_spec.rbにモックを使用したテストを書きました

モックを使用したテストの実装について、過去に自分がまとめた記事

MyHogeTaskJobの動作確認は
「MyHogeTaskBatchのの詳細を隔離したまま、batchという代替品にcallメソッドが届くかどうかの確認をする」という方法でテストをしています。

spec/jobs/my_hoge_task_job_spec.rb

my_hoge_task_job_spec.rb
require 'rails_helper'

RSpec.describe MyHogeTaskJob do
  it 'MyHogeTaskBatchのインスタンスが生成されcallメソッドが呼び出される' do
    batch = MyHogeTaskBatch.new
    allow(MyHogeTaskBatch).to receive(:new).and_return(batch)
    allow(batch).to receive(:call)
    described_class.perform_now
    expect(batch).to have_received(:call)
  end
end

もちろん、詳細なテストもspec/batches/my_hoge_taks_batch_spec.rbに書きます。

my_hoge_taks_batch_spec.rb
require 'rails_helper'

RSpec.describe MyHogeTaskBatch do
  describe '#call' do
    subject { described_class.new.call }
    詳細な内容を確かめるテスト
  end
end

まとめ

以上のような手順でgood_jobを使用してcronジョブを実装できました。
初学者の書いた記事なので、間違っている場合があります。そのときはご指摘していただけると大変助かります

1
2
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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?