Delayed Job を使って実行する処理を、RubyMineでデバッグをする

Rails + Delayed Job な環境で、Delayed Job を使って実行する処理がありました。

例えばこんな感じです。

# Delayed Job で実行
# call_heavy_api中で外部APIを呼んでいるが、その処理が重いとする
Task.delay.call_heavy_api({ foo: 'bar' })

 
そんな中、Delayed Job を使って実行する処理 (上記例では call_heavy_api の中身) をデバッグしたくなったところ、同僚からやり方を聞いたため、メモを残します。

 
目次

 

環境

  • macOS
  • RubyMine 2021.1.1

 

設定

Delayed Jobs は Rake タスクなので、以下の設定を RubyMine に行います。

  • Run > Edit Configurations ...
  • Rakeタスクを追加
    • Name: 任意
    • Configurationタブ
      • Task name: jobs:work
    • Bundlerタブ
      • Run the script in context of the bundle (bundle exec) にチェックを入れる
        • bundlerを使っているため

 

実際のアプリで確認

Rails + Delayed Job なアプリを作って確認してみます。

 

Railsアプリを作成
環境構築
# railsの準備
% bundle init

 
Gemfileを作成

# Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem "rails"

 
APIRailsアプリを作成

% rails new delayed_job_debug --api

% cd delayed_job_debug

 
delayed_job_debugのGemfileに、Delayed JobをActiveRecordで使うためのgemを追記。

# delayed_job_debug/Gemfile

# ...
gem 'delayed_job_active_record'

 
インストール

bundle install

 
Delayed Job の準備をします。

% bin/rails g delayed_job:active_record
Running via Spring preloader in process 13171
      create  bin/delayed_job
       chmod  bin/delayed_job
      create  db/migrate/20210517154917_create_delayed_jobs.rb

% bin/rake db:migrate
Running via Spring preloader in process 13208
== 20210517154917 CreateDelayedJobs: migrating ================================
-- create_table(:delayed_jobs)
   -> 0.0035s
-- add_index(:delayed_jobs, [:priority, :run_at], {:name=>"delayed_jobs_priority"})
   -> 0.0013s
== 20210517154917 CreateDelayedJobs: migrated (0.0050s) =======================

 
config/application.rb にて、Active JobのバックエンドとしてDelayed Job を指定

# config/application.rb
config.active_job.queue_adapter = :delayed_job

 

アプリ追加

重いAPIを呼んでいるモデルを作ります。

今回はDBがなくても確認できるため、モデルファイル app/models/task.rb を作るだけにします。

class Task
  class << self
    # 外部APIの処理が重いとする
    def call_heavy_api(params)
      Rails.logger.warn(params)

      'success'
    end
  end
end

 
上記のメソッドを呼んでいるコントローラを作ります。

% bin/rails g controller tasks
Running via Spring preloader in process 13248
      create  app/controllers/tasks_controller.rb
      invoke  test_unit

 
生成されたファイル app/controllers/task_controller.rb に追記します。

class TasksController < ApplicationController
  def create
    Task.delay.call_heavy_api({ foo: 'bar' })

    render json: { status: 'SUCCESS', data: 'done' }
  end
end

 
config/routes へ追記します。

Rails.application.routes.draw do
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
  post 'tasks/' => 'tasks#create'
end

 

Railsアプリの動作確認

実行します。
f:id:thinkAmi:20210519072647p:plain

 

TerminalからcurlでPOSTします。

% curl -X POST -H "Content-Type: application/json" -d '{}' http://127.0.0.1:3500/tasks/

{"status":"SUCCESS","data":"done"}

 
DBに値が入っています。

f:id:thinkAmi:20210519072635p:plain

 
Delayed Job をターミナルから実行します。

% bin/rake jobs:work

Running via Spring preloader in process 32682
[Worker(host:kamijonoMacBook-Pro.local pid:32682)] Starting job worker
[Worker(host:kamijonoMacBook-Pro.local pid:32682)] Job Task.call_heavy_api (id=3) RUNNING
[Worker(host:kamijonoMacBook-Pro.local pid:32682)] Job Task.call_heavy_api (id=3) COMPLETED after 0.0080
[Worker(host:kamijonoMacBook-Pro.local pid:32682)] 1 jobs processed at 12.7021 j/s, 0 failed

 
Sever development log に実行内容も表示されました。

[Worker(host:kamijonoMacBook-Pro.local pid:32682)] Job Task.call_heavy_api (id=3) RUNNING
{:foo=>"bar"}

 
確認できたため、TerminalでDelayed Job をキャンセルしておきます。

 

デバッグ実行
RubyMineの設定

メニューの Run > Edit Configurations... を選択します。

左上の + ボタンを押して Rake を選択し、以下の内容を追加します。

項目
Name 任意 (job)
Configuration - Task name jobs:work
Bundler - Run the script... チェックを入れる

 

動作確認

Terminalから curl で POST し、DBに保存されることを確認します。

% curl -X POST -H "Content-Type: application/json" -d '{}' http://127.0.0.1:3500/tasks/
{"status":"SUCCESS","data":"done"}

 
確認したいところにブレークポイントを設置します。

f:id:thinkAmi:20210519072617p:plain

 
先ほど作成した設定を選択し、デバッグ実行します。

なお、初回は ruby-debug-ide のインストールが提案されるため、インストールします。

f:id:thinkAmi:20210519072600p:plain

 
しばらく待つと、ブレークポイントで止まりました。変数の中身なども確認できます。

f:id:thinkAmi:20210519072544p:plain

 

ソースコード

確認したRailsアプリはGithubに上げました。
https://github.com/thinkAmi-sandbox/delayed_job_debug-sample